Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.DirectoryServices

''' <summary>
''' 
''' </summary>
''' <remarks></remarks>
Module Build

    Private AssemblyTypes As New Hashtable
    Private AssemblyList As New Hashtable
    Private BuildListGraph As New Hashtable
    Private SortedBuildList As New ArrayList
    Private VisitedNodesForSortedBuildList As New ArrayList
    Private BuildList As New ArrayList
    Private BuildListMapProjToAssmbLoc As New Hashtable
    Private BuildListMapProjToAssmbName As New Hashtable
    Private ProjectSolutionFiles As New Hashtable
    Private lstProjsToBuild As New Hashtable
    Private ProjectsToBuildList As New SortedList
    Private AllProjects As New SortedList
    Private ProjectDirectoryInfo As New Hashtable
    Private ProjectsToAssmb As New Hashtable
    Private WebSvcProjects As New ArrayList
    Private proxiesLoc As New ArrayList
    Private proxiesList As New Hashtable
    Private htOutputPath As New Hashtable
    Private htOutputType As New Hashtable
    Private htCopyTo As New Hashtable
    Private htCopyDirs As New Hashtable
    Private htCopyFiles As New Hashtable
    Private htCopyAssmbTo As New Hashtable
    Private htDeployProjectsToBuild As New Hashtable
    Private htProjGuidAssmb As New Hashtable
    Private htProjectVersion As New Hashtable
    Private htProjectsWithUnusedReferences As New Hashtable
    Private IndProjSets As New ArrayList
    Private lstDeployAppDir As New ArrayList
    Private lstDeployWebSvcDir As New ArrayList
    Private lstDeployWebSvcFiles As New ArrayList
    Private lstAncestors As New ArrayList
    Private lstChildren As New ArrayList

    Private beingVisitedNodes As New ArrayList
    Private cycleDetected As Boolean = False

    Private curAssemblyName As String
    Private LoadFromAssembly As Boolean
    Private assemblyLocation As String
    Private copyOfassemblyLocation As String
    Private blMissingDependency As Boolean = False
    Private strMissingDependency As String = ""
    Private glblBuildMsg As String = ""
    Private errorlogfilename As String = ""

    'Configuration Settings
    Private UBuildConfig As String
    Private buildname As String = ""
    Private projectLocation As String = ""
    Private buildFileLocation As String = ""
    Private genSerializeAssembly As String = ""
    Private buildConfig As String = "Debug"
    Private buildType As String = "Rebuild"
    Private projBuildList As String = ""
    Private loggerName As String = ""
    Private loggerType As String = ""
    Private logFileDir As String = ""
    Private logFileDirError As String = ""
    Private txtLogFileDir As String = "C:\" 'Default location of text log file
    Private txtLogFileMode As TEXTLOGFILEMODE = TEXTLOGFILEMODE.APPEND
    Private loggerInfo As Boolean = False
    Private setSgen As Boolean = True
    Private dispXMLoutput As Boolean = False
    Private dispBuildList As Boolean = False
    Private manageAssemblyVersion As Boolean = False
    Private autoIncrementAssemblyRevNumber As Boolean = False
    Private resetAssemblyRevNumber As Boolean = False
    Private alwaysUseMSBuild As Boolean = False
    Private msBuildErrorLogsByDate As Boolean = True
    Private blCreateASingleMSBuildErrorLogFile As Boolean = True
    Private blParseUBuildErrorLog As Boolean = False
    Private blUseStylesheetForErrorLogs As Boolean = False
    Private reSyncCode As Boolean = False
    Private buildAllProjects As Boolean = False
    Private resyncOptions As String = "-f -R -S"
    Private DEVENV_VS2003 As String = "C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.com"
    Private DEVENV_VS2005 As String = "C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com"
    Private DEVENV_VS2008 As String = "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com"
    Private MSBUILD_2_0 As String = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe"
    Private MSBUILD_3_5 As String = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
    Private MKS_SI As String = "C:\Program Files\MKS\IntegrityClient\bin\si.exe"
    Private BuildVersionInfo As String = String.Empty
    Private BuildVersionInfoFile As String = String.Empty
    Private BuildVersionControlFileLocation As String = String.Empty
    Private BuildVersionInfoDir As String = ""
    Private UBuildErrorDetailFile As String = String.Empty
    Private UBuildSingleMsbuildErrorLogFile As String = String.Empty
    Private StyleSheetLocation As String = String.Empty
    Private txtLogFile As String = String.Empty
    Private blErrLogReady As Boolean
    Private buildtoolName As String = String.Empty
    Private targetFrameworkVersion As String = String.Empty
    Private buildtoolLocation As String = String.Empty
    Private onFailureTryWith As String
    Private buildUsing As BUILDTOOL
    Private onFailureBuildUsing As BUILDTOOL
    Private msbuildver As MSBUILDVERSION = MSBUILDVERSION.TWO
    Private onFailureDeleteSlnFileAndRebuild As Boolean
    Private alwaysBuildProject As Boolean
    Private dispPopupBuildMsg As Boolean
    Private bldispUnusedReferences As Boolean
    Private bldispWebReferences As Boolean
    Private webreferencebehavior As WEBREFBEHAVIOR = WEBREFBEHAVIOR.ALL
    Private buildProxyProjects As Boolean
    Private sendnotification As Boolean
    Private locksdir As String = "C:\Locks"
    Private buildlockfilename As String = "UBuild.lock"
    Private currentProcessId As String
    Private buildlockfile As String
    Private lockdirinfo As DirectoryInfo
    Private blAtLeastOneProjFailedInBuild As Boolean = False
    Private blReSyncInParallel As Boolean = False
    Private blParallelBuild As Boolean = False
    Private blContinueOnFailure As Boolean = False
    Private ParallelBuildLog As ArrayList = New ArrayList
    Private ParallelReSyncSourceLog As ArrayList = New ArrayList

    Private NOTIFICATION_SERVER As String
    Private NOTIFICATION_SERVER_PORT As Integer

    'UBuild Error detail
    Private failedprojectname As String = ""
    Private errfilename As String
    Private errordesc As String = ""
    Private errorlinenumber As String = ""
    Private errorcode As String = ""
    Private revnumber As String
    Private lockedin As String = ""
    Private createdauthorname As String = ""
    Private lockedbyauthorname As String = ""
    Private createddatetime As String = ""
    Private lockeddatetime As String = ""

    'Managing Assembly version numbers
    Private majorVer As String
    Private minorVer As String
    Private buildNumber As String
    Private buildRevision As String
    Private buildRevisionFormatted As String = String.Empty
    Private autobuildnumber As String
    Private newBuildNumber As String

    'UBuild time taken
    Private startTime As DateTime
    Private endTime As DateTime
    Private elapsedTime As TimeSpan

    Private Const ERROR_DIR As String = "Error"
    Private Const DEFAULT_BUILD_CONFIGURATION As String = "debug"
    Private Const FILEEXT_XML As String = ".xml"
    Private Const UBUILD_UNUSEDREF_LOG_FILENAME As String = "UBuild-UnusedReferences.log"
    Private Const UBUILD_WEBREFERENCES_LOG_FILENAME As String = "UBuild-WebReferences.log"
    Private Const UBUILD_PROJECTINFO_LOG_FILENAME_XML As String = "UBuild-ProjectsInfo.log.xml"
    Private Const UBUILD_OUTPUT_LOG_FILENAME As String = "UBuild_Output.log"
    Private Const UBUILD_ERR_DETAIL As String = "UBuild-ErrDetails"
    Private Const UBUILD_MSBUILD_SINGLEERRORLOG_FILENAME As String = "UBuild-ErrorLog"
    Private Const UBUILD_ERR_DETAIL_STYLESHEET As String = "UBuild-ErrorDetail.xsl"
    Private Const UBUILD_MSBUILD_SINGLEERRORLOG_FILENAME_STYLESHEET As String = "UBuild-Error-log.xsl"
    Private Const UBUILD_PROJECTINFO_STYLESHEET As String = "UBuild-ProjectInfo.xsl"
    Private Const UBUILD_PROGRESS_FILENAME As String = "UBuildProgress.txt"
    Private Const UBUILD_AUTOINCREMENT_BUILDVERSION_COUNTER_FILENAME As String = "AssemblyRevisionNumber.txt"
    Private Const UBUILD_BUILDNUMBER_FILENAME As String = "BuildNumber.txt"
    Private Const UBUILD_BUILDVERSIONINFO_FILENAME As String = "BuildVersionInfo.xml"
    Private Const UBUILD_TXTLOGFILEDIR_DEFAULT_LOCATION As String = "C:\"
    Private Const UBUILD_LOG_DEFAULT_LOCATION As String = "C:\UBuildLog\"

    Private Const WEBREFDATATBL_COLUMNNAME_REFERENCE As String = "Reference"
    Private Const WEBREFDATATBL_COLUMNNAME_URL As String = "Url"
    Private Const WEBREFDATATBL_COLUMNNAME_BEHAVIOR As String = "Behavior"
    Private Const WEBREFDATATBL_COLUMNNAME_REFERREDBY As String = "ReferredBy"
    Private Const WEBREFDATATBL_COLUMNNAME_PROJECT As String = "Project"

    Delegate Sub ParallelBuildDelegate(ByVal projname As String, ByVal projcount As Integer)
    Delegate Sub ParallelReSyncSourceDelegate(ByVal projname As String)

    Public NosOfParallelBuild As Integer
    Public pllBuildStatusCd As Integer
    Public blAtLeastOneProjFailedInParalellBuild As Boolean
    Public NosOfProjectsToReSync As Integer
    Public NosOfProjectsBuiltSuccessfully As Integer
    Public NosOfProjectToBuild As Integer

#Region "Enumerations"

    Public Enum TEXTLOGFILEMODE As Integer
        APPEND = 1
        CREATE = 2
    End Enum

    Public Enum BUILDTOOL
        NONE
        AUTOSELECT
        MSBUILD_2_0
        MSBUILD_3_5
        VS2008
        VS2005
        VS2003
    End Enum

    Public Enum MSBUILDVERSION
        TWO
        THREE
    End Enum

    Private Enum DOTNETVERSION
        ONE = 1
        TWO = 2
    End Enum

    Private Enum WEBREFBEHAVIOR
        ALL = 1
        DYNAMIC = 2
        [STATIC] = 3
    End Enum

#End Region

#Region "Main"

    Public Function Main() As Integer

        Dim exitCode As Integer

        'add an unhandled exceptions handler 
        Dim currentDomain As AppDomain = AppDomain.CurrentDomain
        AddHandler currentDomain.UnhandledException, AddressOf UnhandledExceptionHandler

        'Setting up distributed synchronization using self-regulating queue

        currentProcessId = System.Diagnostics.Process.GetCurrentProcess.Id.ToString

        '1. (a) Create the C:\Locks directory if not exisitng
        If Not Directory.Exists(locksdir) Then
            Directory.CreateDirectory(locksdir)
        End If
        '(b) Create the directory info object
        lockdirinfo = New DirectoryInfo(locksdir)

        '2. Create the lockfile full path name
        buildlockfile = AddBackSlashAtTheEnd(locksdir) + buildlockfilename
        '3.Wait till the lock is released by another UBuild process
        While IsLocked(buildlockfile)
            'zzz
            Thread.Sleep(60000)
        End While
        '4.If more than one UBuild process is ready to acquire the lock, check if can proceed to get the lock - Entering 'critical section' 
        While CannotProceed(currentProcessId)
            'zzz
            Thread.Sleep(60000)
        End While
        '5.Create the lock before proceeding with the build
        CreateLock(buildlockfile)

        startTime = Now

        Try
            If ProcessCommandLineArgs(System.Environment.GetCommandLineArgs()) Then
                If ParseConfigFile() Then
                    If dispXMLoutput Then Output("<buildsteps>")
                    If Setup() Then

                        LoadAllProjectsLocation()

                        LoadProjectsToBuildLocation()

                        CreateDependencyGraphFromProjects()

                        'Check for circular dependency and proceeed if no cycle is detected
                        If Not DetectCircularDependency() Then

                            'Generate the 'ordered' build list
                            GenerateBuildList()

                            'Detect and display web-references
                            If bldispWebReferences Then
                                DisplayWebReferences() ' In a text log file
                                DisplayWebReferencesXML() 'In xml log file
                            End If

                            'Resynchronize code 
                            If reSyncCode Then
                                ReSynchronizeProjectsToBuild()
                                UpdateProjectProperties()
                            End If

                            'Display the build list
                            If dispBuildList Then
                                DisplayBuildList()
                            End If

                            'Setup the build version number
                            SetupBuildVersionNumber()

                            'Perform Build - Parallel OR Sequential
                            If blParallelBuild Then
                                exitCode = DoParallelBuild()
                            Else
                                exitCode = DoBuild()
                            End If

                            'If ManageAssemblyVersion = TRUE (i.e. the string BuildVersionInfo will have the build number) then create the BuildVersionInfo file for archiving
                            'if the 'BuildVersionInfoFile' AND BuildVersionInfo is not empty
                            If String.Compare(BuildVersionInfoFile, String.Empty) <> 0 AndAlso String.Compare(BuildVersionInfo, String.Empty) <> 0 Then
                                ArchiveBuildVersionInfo()

                                'Copy the <BuildVersionInfo> to <VersionControlFileLocation> so that when setting up build version number
                                'SetupBuildVersionNumber() we can look in this location to get the current build number.
                                'The assumption here is that the files in <VersionControlFileLocation> information is provided AND will not be deleted

                                Dim dest As String = AddBackSlashAtTheEnd(BuildVersionControlFileLocation) & UBUILD_BUILDVERSIONINFO_FILENAME
                                Dim src As String = BuildVersionInfoFile

                                If String.Compare(src, dest, True) <> 0 Then 'If <VersionControlFileLocation> is provided then only do the copy
                                    File.Copy(src, dest, True)
                                End If
                                
                            End If

                            'Display unused referecnes
                            If bldispUnusedReferences Then
                                DisplayUnusedReferences() ' In a text log file
                                DisplayUnusedReferencesXML() 'In a xml log file
                            End If

                            'Log the starttime (used as tiemstamp for the current build) in the 'BuildVersionInfo' file
                            LogStartTimestamp()
                        Else
                            'Detected circular reference
                            exitCode = -1
                        End If '//Check circular dependency
                    End If '// Check Setup
                End If '//Check config file
            End If '//Check command line arguments

            endTime = Now
            elapsedTime = endTime.Subtract(startTime)

            If dispXMLoutput Then
                Output("<duration>" + elapsedTime.TotalSeconds.ToString("0.000") + "</duration>")
            Else
                Output("Time Taken: " + elapsedTime.TotalSeconds.ToString("0.000") + " secs", ConsoleTools.ConsoleColor.yellow)
            End If

            If dispXMLoutput Then Output("</buildsteps>")

            WriteLog("Build Finished ... " + endTime.ToString)
            WriteLog("Time Taken: " + elapsedTime.TotalSeconds.ToString("0.000") + " secs")

        Catch ex As Exception
            exitCode = -1
            If dispXMLoutput Then
                Output("<message loc=""main""><![CDATA[" + ex.ToString + "]]></message>")
            Else
                Output("Runtime Exception !" + vbCrLf + ex.ToString, ConsoleTools.ConsoleColor.red)
            End If
        Finally
            'Release the lock
            ReleaseLock(buildlockfile)

            'Delete the entry from the queue
            If File.Exists(AddBackSlashAtTheEnd(locksdir) + currentProcessId + ".txt") Then
                File.Delete(AddBackSlashAtTheEnd(locksdir) + currentProcessId + ".txt")
            End If
        End Try

        Return exitCode

    End Function

#End Region

#Region " Configuration And Setup"

    Private Function ProcessCommandLineArgs(ByVal iParameters As String()) As Boolean
        Dim cmdLineArgOk As Boolean = True

        If iParameters.Length <> 3 Then
            DisplayUsage("ERROR ! Incorrect number of arguments")
            cmdLineArgOk = False
        Else
            If iParameters(1).Trim.ToUpper.Equals("/CONFIG") Then
                If File.Exists(iParameters(2).Trim) Then
                    UBuildConfig = iParameters(2).Trim
                Else
                    DisplayUsage("ERROR ! Unable to locate " + iParameters(2))
                    cmdLineArgOk = False
                End If
            Else
                DisplayUsage("ERROR! Invalid flag")
                cmdLineArgOk = False
            End If
        End If

        Return cmdLineArgOk

    End Function

    Private Function ParseConfigFile() As Boolean
        Dim configFileOk As Boolean
        Dim xmldoc As XmlDocument
        Dim xnl As XmlNodeList
        Dim element As XmlElement
        Dim id As String = String.Empty
        Dim copytoloc As String

        Try
            xmldoc = New XmlDocument
            xmldoc.Load(UBuildConfig)

            '<BuildName>
            If xmldoc.GetElementsByTagName("BuildName").Count = 1 Then
                buildname = xmldoc.GetElementsByTagName("BuildName").Item(0).InnerText.Trim
            End If

            '<ProjectLocation>
            If xmldoc.GetElementsByTagName("ProjectLocation").Count = 1 Then
                projectLocation = AddBackSlashAtTheEnd(xmldoc.GetElementsByTagName("ProjectLocation").Item(0).InnerText)
            End If

            '<BuildRefPath>
            If xmldoc.GetElementsByTagName("BuildRefPath").Count = 1 Then
                buildFileLocation = AddBackSlashAtTheEnd(xmldoc.GetElementsByTagName("BuildRefPath").Item(0).InnerText)
            End If

            '<ProjectsToBuild>
            If xmldoc.GetElementsByTagName("ProjectsToBuild").Count = 1 Then
                projBuildList = xmldoc.GetElementsByTagName("ProjectsToBuild").Item(0).InnerText
                'Check if we want to build all projects
                If (projBuildList = "*") OrElse String.Compare(projBuildList, "ALL", True) = 0 Then
                    buildAllProjects = True
                End If
            End If

            '<BuildConfiguration>
            If xmldoc.GetElementsByTagName("BuildConfiguration").Count = 1 Then
                buildConfig = xmldoc.GetElementsByTagName("BuildConfiguration").Item(0).InnerText
                If buildConfig = String.Empty Then
                    buildConfig = DEFAULT_BUILD_CONFIGURATION
                ElseIf String.Compare(buildConfig, "debug", True) <> 0 AndAlso String.Compare(buildConfig, "release", True) <> 0 Then
                    buildConfig = DEFAULT_BUILD_CONFIGURATION
                End If
            End If

            '<GenerateSerializationAssemblies>
            If xmldoc.GetElementsByTagName("GenerateSerializationAssemblies").Count = 1 Then
                genSerializeAssembly = xmldoc.GetElementsByTagName("GenerateSerializationAssemblies").Item(0).InnerText
                Select Case genSerializeAssembly.ToUpper
                    Case "ON"
                        genSerializeAssembly = "On"
                    Case "OFF"
                        genSerializeAssembly = "Off"
                    Case Else
                        setSgen = False
                End Select
            End If

            '<BuildType>
            If xmldoc.GetElementsByTagName("BuildType").Count = 1 Then
                Dim typeofbuild As String = xmldoc.GetElementsByTagName("BuildType").Item(0).InnerText.ToLower
                Select Case typeofbuild
                    Case "minor", "build", "1"
                        buildType = "Build"
                    Case "major", "rebuild", "2"
                        buildType = "Rebuild"
                    Case Else
                        buildType = "Rebuild"
                End Select
            End If

            '<ReSyncCode options="" parallel="">
            If xmldoc.GetElementsByTagName("ReSyncCode").Count = 1 Then
                reSyncCode = (xmldoc.GetElementsByTagName("ReSyncCode").Item(0).InnerText.ToUpper = "TRUE")
                If reSyncCode And xmldoc.GetElementsByTagName("ReSyncCode").Item(0).Attributes.Count = 1 Then
                    Dim attrName As String = xmldoc.GetElementsByTagName("ReSyncCode").Item(0).Attributes(0).Name
                    If Not attrName Is Nothing And String.Compare(attrName, "options", True) = 0 Then
                        resyncOptions = xmldoc.GetElementsByTagName("ReSyncCode").Item(0).Attributes(0).Value
                        If String.Compare(resyncOptions.Trim, "default", True) = 0 OrElse resyncOptions = String.Empty Then
                            resyncOptions = " -f -R -S "
                        End If
                    End If
                End If

                Dim attribcol As XmlAttributeCollection = xmldoc.GetElementsByTagName("ReSyncCode").Item(0).Attributes
                For Each attrib As XmlAttribute In attribcol
                    Dim attribname As String = attrib.Name.ToLower()
                    Select Case attribname
                        Case "parallel"
                            blReSyncInParallel = (attrib.Value.ToUpper = "TRUE")
                    End Select
                Next
            End If

            '<LoggerPath>
            If xmldoc.GetElementsByTagName("LoggerPath").Count = 1 Then
                loggerName = xmldoc.GetElementsByTagName("LoggerPath").Item(0).InnerText
            End If

            '<Type>
            If xmldoc.GetElementsByTagName("Type").Count = 1 Then
                loggerType = xmldoc.GetElementsByTagName("Type").Item(0).InnerText
            End If

            '<LogFileDirectory>
            If xmldoc.GetElementsByTagName("LogFileDirectory").Count = 1 Then
                logFileDir = AddBackSlashAtTheEnd(xmldoc.GetElementsByTagName("LogFileDirectory").Item(0).InnerText)
            Else
                logFileDir = UBUILD_LOG_DEFAULT_LOCATION
            End If

            '<TextLogPath>
            If xmldoc.GetElementsByTagName("TextLogPath").Count = 1 Then
                txtLogFileDir = AddBackSlashAtTheEnd(xmldoc.GetElementsByTagName("TextLogPath").Item(0).InnerText)
                If String.IsNullOrEmpty(txtLogFileDir) Then
                    txtLogFileDir = UBUILD_TXTLOGFILEDIR_DEFAULT_LOCATION
                End If
            Else
                txtLogFileDir = UBUILD_TXTLOGFILEDIR_DEFAULT_LOCATION
            End If

            '<TextLogFile>
            If xmldoc.GetElementsByTagName("TextLogFile").Count = 1 Then
                Dim tmplogfile As String = xmldoc.GetElementsByTagName("TextLogFile").Item(0).InnerText.Trim
                If String.Compare(tmplogfile, String.Empty) = 0 Then
                    txtLogFile = txtLogFileDir + UBUILD_PROGRESS_FILENAME
                Else
                    txtLogFile = txtLogFileDir + tmplogfile
                End If

                'Get the mode
                Dim attribcol As XmlAttributeCollection = xmldoc.GetElementsByTagName("TextLogFile").Item(0).Attributes
                For Each attrib As XmlAttribute In attribcol
                    Dim attribname As String = attrib.Name.ToLower()
                    Select Case attribname
                        Case "mode"
                            txtLogFileMode = CType(attrib.Value, TEXTLOGFILEMODE)
                    End Select
                Next
            Else
                txtLogFile = txtLogFileDir + UBUILD_PROGRESS_FILENAME
            End If

            '<MSBuildErrorLogsByDate>
            If xmldoc.GetElementsByTagName("MSBuildErrorLogsByDate").Count = 1 Then
                msBuildErrorLogsByDate = (xmldoc.GetElementsByTagName("MSBuildErrorLogsByDate").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<CreateSingleMSBuildErrorLogFile>
            If xmldoc.GetElementsByTagName("CreateSingleMSBuildErrorLogFile").Count = 1 Then
                blCreateASingleMSBuildErrorLogFile = (xmldoc.GetElementsByTagName("CreateSingleMSBuildErrorLogFile").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<ParseUBuildErrorLog>
            If xmldoc.GetElementsByTagName("ParseUBuildErrorLog").Count = 1 Then
                blParseUBuildErrorLog = (xmldoc.GetElementsByTagName("ParseUBuildErrorLog").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<UseStyleSheetForLogs>
            If xmldoc.GetElementsByTagName("UseStyleSheetForLogs").Count = 1 Then
                blUseStylesheetForErrorLogs = (xmldoc.GetElementsByTagName("UseStyleSheetForLogs").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<StyleSheetLocation>
            If xmldoc.GetElementsByTagName("StyleSheetLocation").Count = 1 Then
                StyleSheetLocation = xmldoc.GetElementsByTagName("StyleSheetLocation").Item(0).InnerText
            End If

            '<AlwaysUseMSBuild>
            If xmldoc.GetElementsByTagName("AlwaysUseMSBuild").Count = 1 Then
                alwaysUseMSBuild = (xmldoc.GetElementsByTagName("AlwaysUseMSBuild").Item(0).InnerText.ToUpper = "TRUE")
                If alwaysUseMSBuild And xmldoc.GetElementsByTagName("AlwaysUseMSBuild").Item(0).Attributes.Count = 1 Then
                    Dim attrName As String = xmldoc.GetElementsByTagName("AlwaysUseMSBuild").Item(0).Attributes(0).Name.Trim
                    If Not attrName Is Nothing And String.Compare(attrName, "version", True) = 0 Then
                        Dim _msbuildver As String = xmldoc.GetElementsByTagName("AlwaysUseMSBuild").Item(0).Attributes(0).Value.Trim
                        Select Case _msbuildver
                            Case "2.0", "2", "VS2005"
                                msbuildver = MSBUILDVERSION.TWO
                            Case "3.0", "3", "3.5", "VS2008"
                                msbuildver = MSBUILDVERSION.THREE
                            Case Else
                                msbuildver = MSBUILDVERSION.TWO
                        End Select
                    Else
                        msbuildver = MSBUILDVERSION.TWO '// if alwaysUseMSBUILD=TRUE and provided attribute is anything but "version" then default two MSBUILD 2.0
                    End If
                End If
            End If

            '../<UBuild>/<ConfigSettings>/<BuildTool>/<Name>
            If Not xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/Name") Is Nothing Then
                buildtoolName = xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/Name").InnerText.Trim.ToUpper
            End If

            '../<UBuild>/<ConfigSettings>/<BuildTool>/<TargetFrameworkVersion>
            If Not xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/TargetFrameworkVersion") Is Nothing Then
                targetFrameworkVersion = xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/TargetFrameworkVersion").InnerText.Trim.ToLower
            End If

            '../<UBuild>/<ConfigSettings>/<BuildTool>/<Location>
            If Not xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/Location") Is Nothing Then
                buildtoolLocation = xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/Location").InnerText.Trim.ToUpper
            End If

            '../<UBuild>/<ConfigSettings>/<BuildTool>/<OnFailureTryWith>
            If Not xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/OnFailureTryWith") Is Nothing Then
                onFailureTryWith = xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/OnFailureTryWith").InnerText.Trim.ToUpper
            End If

            '../<UBuild>/<ConfigSettings>/<BuildTool>/<OnFailureDeleteSlnFileAndReBuild>
            If Not xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/OnFailureDeleteSlnFileAndReBuild") Is Nothing Then
                onFailureDeleteSlnFileAndRebuild = (xmldoc.SelectSingleNode("/UBuild/ConfigSettings/BuildTool/OnFailureDeleteSlnFileAndReBuild").InnerText.Trim.ToUpper = "TRUE")
            End If

            '<AlwaysBuildProject>
            If xmldoc.GetElementsByTagName("AlwaysBuildProject").Count = 1 Then
                alwaysBuildProject = (xmldoc.GetElementsByTagName("AlwaysBuildProject").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<DisplayPopUpBuildMsg>
            If xmldoc.GetElementsByTagName("DisplayPopUpBuildMsg").Count = 1 Then
                dispPopupBuildMsg = (xmldoc.GetElementsByTagName("DisplayPopUpBuildMsg").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<DisplayUnusedReferences>
            If xmldoc.GetElementsByTagName("DisplayUnusedReferences").Count = 1 Then
                bldispUnusedReferences = (xmldoc.GetElementsByTagName("DisplayUnusedReferences").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<DisplayWebReferences>'
            If xmldoc.GetElementsByTagName("DisplayWebReferences").Count = 1 Then
                bldispWebReferences = (xmldoc.GetElementsByTagName("DisplayWebReferences").Item(0).InnerText.ToUpper = "TRUE")
                If bldispWebReferences Then
                    Dim dispwebrefelement As XmlElement = xmldoc.GetElementsByTagName("DisplayWebReferences").Item(0)
                    If dispwebrefelement.HasAttributes Then
                        Dim attrcol As XmlAttributeCollection = dispwebrefelement.Attributes
                        For Each attr As XmlAttribute In attrcol
                            Select Case attr.Name.ToLower
                                Case "behavior"
                                    Select Case attr.Value.ToLower
                                        Case "all"
                                            webreferencebehavior = WEBREFBEHAVIOR.ALL
                                        Case "static"
                                            webreferencebehavior = WEBREFBEHAVIOR.STATIC
                                        Case "dynamic"
                                            webreferencebehavior = WEBREFBEHAVIOR.DYNAMIC
                                        Case Else
                                            webreferencebehavior = WEBREFBEHAVIOR.ALL
                                    End Select
                            End Select
                        Next
                    End If
                End If
            End If

            '<ConsoleOutputInXML>
            If xmldoc.GetElementsByTagName("ConsoleOutputInXML").Count = 1 Then
                dispXMLoutput = (xmldoc.GetElementsByTagName("ConsoleOutputInXML").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<DisplayBuildList>
            If xmldoc.GetElementsByTagName("DisplayBuildList").Count = 1 Then
                dispBuildList = (xmldoc.GetElementsByTagName("DisplayBuildList").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<ParallelBuild>
            If xmldoc.GetElementsByTagName("ParallelBuild").Count = 1 Then
                blParallelBuild = (xmldoc.GetElementsByTagName("ParallelBuild").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<ContinueOnFailure>
            If xmldoc.GetElementsByTagName("ContinueOnFailure").Count = 1 Then
                blContinueOnFailure = (xmldoc.GetElementsByTagName("ContinueOnFailure").Item(0).InnerText.ToUpper = "TRUE")
            End If


            '<UpdateAssemblyVersion>
            If xmldoc.GetElementsByTagName("UpdateAssemblyVersion").Count = 1 Then
                manageAssemblyVersion = (xmldoc.GetElementsByTagName("UpdateAssemblyVersion").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<AutoIncrementRevisionNumber>
            If xmldoc.GetElementsByTagName("AutoIncrementRevisionNumber").Count = 1 Then
                autoIncrementAssemblyRevNumber = (xmldoc.GetElementsByTagName("AutoIncrementRevisionNumber").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<ResetRevisionNumberToZero>
            If xmldoc.GetElementsByTagName("ResetRevisionNumberToZero").Count = 1 Then
                resetAssemblyRevNumber = (xmldoc.GetElementsByTagName("ResetRevisionNumberToZero").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<AssemblyVersionControlFileLocation>
            If xmldoc.GetElementsByTagName("VersionControlFileLocation").Count = 1 Then
                BuildVersionControlFileLocation = xmldoc.GetElementsByTagName("VersionControlFileLocation").Item(0).InnerText.Trim
            Else
                BuildVersionControlFileLocation = UBUILD_LOG_DEFAULT_LOCATION
            End If

            '<BuildVersionInfo>
            If xmldoc.GetElementsByTagName("BuildVersionInfo").Count = 1 Then
                BuildVersionInfoFile = xmldoc.GetElementsByTagName("BuildVersionInfo").Item(0).InnerText.Trim

                Dim finfo As FileInfo = New FileInfo(BuildVersionInfoFile)
                BuildVersionInfoDir = finfo.DirectoryName
                If Not Directory.Exists(BuildVersionInfoDir) Then
                    Directory.CreateDirectory(BuildVersionInfoDir)
                End If
            Else
                BuildVersionInfoFile = AddBackSlashAtTheEnd(UBUILD_LOG_DEFAULT_LOCATION) & UBUILD_BUILDVERSIONINFO_FILENAME
            End If

            '<BuildProxyProjects>
            If xmldoc.GetElementsByTagName("BuildProxyProjects").Count = 1 Then
                buildProxyProjects = (xmldoc.GetElementsByTagName("BuildProxyProjects").Item(0).InnerText.ToUpper = "TRUE")
            End If

            '<Proxies>
            xnl = xmldoc.GetElementsByTagName("Proxies")
            For Each element In xnl
                Dim childnodelist As XmlNodeList = element.ChildNodes
                For Each cnode As XmlElement In childnodelist
                    If Not cnode.InnerText Is Nothing And cnode.InnerText.Length > 0 And Not proxiesLoc.Contains(cnode.InnerText) Then
                        proxiesLoc.Add(AddBackSlashAtTheEnd(cnode.InnerText))
                    End If
                Next
            Next

            '<Notify>
            If xmldoc.GetElementsByTagName("Notify").Count = 1 Then
                sendnotification = (xmldoc.GetElementsByTagName("Notify").Item(0).InnerText.ToUpper = "TRUE")
                If sendnotification Then
                    Dim notifyelement As XmlElement = xmldoc.GetElementsByTagName("Notify").Item(0)
                    If notifyelement.HasAttribute("server") And notifyelement.HasAttribute("port") Then
                        NOTIFICATION_SERVER = notifyelement.GetAttribute("server").Trim
                        NOTIFICATION_SERVER_PORT = Integer.Parse(notifyelement.GetAttribute("port").Trim)
                    Else
                        sendnotification = False
                    End If
                End If
            End If

            '<Deploy>
            xnl = xmldoc.GetElementsByTagName("Deploy")
            For Each element In xnl
                If element.HasChildNodes Then
                    Dim childnodelist As XmlNodeList = element.ChildNodes
                    For Each cnode As XmlElement In childnodelist

                        If cnode.HasAttribute("id") Then
                            id = cnode.GetAttribute("id").ToLower
                            copytoloc = cnode.InnerText.ToLower
                            If Not copytoloc Is Nothing And copytoloc.Length > 0 And Not id Is Nothing And id.Length > 0 And Not htCopyTo.Contains(id) Then
                                htCopyTo.Add(id, AddBackSlashAtTheEnd(copytoloc))
                            End If

                            If cnode.HasAttribute("copydirs") And Not htCopyDirs.Contains(id) Then
                                Dim dirlist As New ArrayList
                                Dim dirs() As String = cnode.GetAttribute("copydirs").Split(",")
                                If dirs.Length > 0 Then
                                    For i As Integer = 0 To dirs.Length - 1
                                        If Not dirlist.Contains(dirs(i)) Then
                                            dirlist.Add(dirs(i))
                                        End If
                                    Next
                                    htCopyDirs.Add(id, dirlist)
                                End If
                            End If

                            If cnode.HasAttribute("copyfiles") And Not htCopyFiles.Contains(id) Then
                                Dim filelist As New ArrayList
                                Dim files() As String = cnode.GetAttribute("copyfiles").Split(",")
                                If files.Length > 0 Then
                                    For i As Integer = 0 To files.Length - 1
                                        If Not filelist.Contains(files(i)) Then
                                            filelist.Add(files(i))
                                        End If
                                    Next
                                    htCopyFiles.Add(id, filelist)
                                End If
                            End If

                        End If

                        'Get the specific types of folders to be deploy - for the <Application> tag with id="exe"
                        If String.Compare(id, "exe", True) = 0 And cnode.HasAttribute("copydirs") Then
                            Dim dirs() As String = cnode.GetAttribute("copydirs").Split(",")
                            If dirs.Length > 0 Then
                                For i As Integer = 0 To dirs.Length - 1
                                    If Not lstDeployAppDir.Contains(dirs(i)) Then
                                        lstDeployAppDir.Add(dirs(i))
                                    End If
                                Next
                            End If
                        End If

                        'Get the specific types of folders and files to be deploy for web services
                        If String.Compare(id, "websvc", True) = 0 Then

                            If cnode.HasAttribute("copydirs") Then
                                Dim dirs() As String = cnode.GetAttribute("copydirs").Split(",")
                                If dirs.Length > 0 Then
                                    For i As Integer = 0 To dirs.Length - 1
                                        If Not lstDeployWebSvcDir.Contains(dirs(i)) Then
                                            lstDeployWebSvcDir.Add(dirs(i))
                                        End If
                                    Next
                                End If
                            End If
                            If cnode.HasAttribute("copyfiles") Then
                                Dim files() As String = cnode.GetAttribute("copyfiles").Split(",")
                                If files.Length > 0 Then
                                    For i As Integer = 0 To files.Length - 1
                                        If Not lstDeployWebSvcFiles.Contains(files(i)) Then
                                            lstDeployWebSvcFiles.Add(files(i))
                                        End If
                                    Next
                                End If
                            End If

                        End If

                    Next cnode
                End If
            Next element

            If projectLocation Is Nothing OrElse projectLocation.Length = 0 Then
                Console.WriteLine("Missing project location in configuration settings !")
                configFileOk = False
            ElseIf buildFileLocation Is Nothing OrElse buildFileLocation.Length = 0 Then
                Console.WriteLine("Missing reference path information in configuration settings !")
                configFileOk = False
            ElseIf Not buildAllProjects AndAlso projBuildList Is Nothing OrElse projBuildList.Length = 0 Then
                Console.WriteLine("Missing project to build list in configuration settings !")
                configFileOk = False
            Else
                configFileOk = True
            End If

        Catch ex As Exception
            Console.WriteLine("Configuration file problem!" + vbCrLf + ex.Message)
            configFileOk = False
        End Try

        Return configFileOk

    End Function

    Private Function Setup() As Boolean
        Dim timestamp As String
        Dim sw As StreamWriter
        Dim setupOk As Boolean = True

        'Create the tiemstamp
        timestamp = CreateTimeStamp(startTime)

        'Create the default log location directory, if necessary
        If Not Directory.Exists(UBUILD_LOG_DEFAULT_LOCATION) Then
            Directory.CreateDirectory(UBUILD_LOG_DEFAULT_LOCATION)
        End If

        'Check if <TextLogPath> is available
        If String.Compare(txtLogFileDir, String.Empty) = 0 Then
            If dispXMLoutput Then
                Output("<step name=""Setup"" status=""error"" >Missing text log file directory (<TextLogPath></TextLogPath>) information : </step>")
            Else
                Output("Setup() ERROR ! Missing text log file directory (<TextLogPath></TextLogPath>) information", ConsoleTools.ConsoleColor.red)
            End If
            setupOk = False
        Else
            If Not Directory.Exists(txtLogFileDir) Then
                Directory.CreateDirectory(txtLogFileDir)
            End If
        End If

        'Check <TextLogFile> is available or not and its 'mode'
        If String.Compare(txtLogFile, String.Empty) <> 0 Then
            If txtLogFileMode = TEXTLOGFILEMODE.APPEND Then
                If Not File.Exists(txtLogFile) Then
                    sw = File.CreateText(txtLogFile)
                    sw.Close()
                End If
            ElseIf txtLogFileMode = TEXTLOGFILEMODE.CREATE Then
                If File.Exists(txtLogFile) Then
                    File.Delete(txtLogFile)
                End If
                sw = File.CreateText(txtLogFile)
                sw.Close()
            End If
            sw = Nothing
        Else
            If dispXMLoutput Then
                Output("<step name=""Setup"" status=""error"">Text Log file name cannot be empty</step>")
            Else
                Output("Setup() ERROR ! Text Log file name cannot be empty", ConsoleTools.ConsoleColor.red)
            End If
            setupOk = False
        End If

        'Check if <BuildRefPath> is available
        If String.Compare(buildFileLocation, String.Empty) <> 0 Then
            If Not Directory.Exists(buildFileLocation) Then
                Directory.CreateDirectory(buildFileLocation)
            End If
        Else
            If dispXMLoutput Then
                Output("<step name=""Setup"" status=""error"" >Missing <BuildRefPath> information</step>")
            Else
                Output("Setup() ERROR ! Missing <BuildRefPath> information", ConsoleTools.ConsoleColor.red)
            End If
            setupOk = False
        End If

        'Check if <ProjectsToBuild> information is available
        If Not buildAllProjects AndAlso String.Compare(projBuildList, String.Empty) <> 0 AndAlso Not File.Exists(projBuildList) Then
            If dispXMLoutput Then
                Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to find the project to build list : " + projBuildList + "</step>")
            Else
                Output("Setup() ERROR ! Unable to find the project to build list : " + projBuildList, ConsoleTools.ConsoleColor.red)
            End If
            WriteLog("Setup() ERROR ! Unable to find the project to build list : " + projBuildList)
            setupOk = False
        End If

        'Setup the buildtool 
        If alwaysUseMSBuild Then
            Select Case msbuildver
                Case MSBUILDVERSION.TWO
                    buildUsing = BUILDTOOL.MSBUILD_2_0
                Case MSBUILDVERSION.THREE
                    buildUsing = BUILDTOOL.MSBUILD_3_5
                Case Else
                    buildUsing = BUILDTOOL.MSBUILD_2_0
            End Select
        Else
            Select Case buildtoolName
                Case "MSBUILD", "MSBUILD_2_0"
                    buildUsing = BUILDTOOL.MSBUILD_2_0
                Case "MSBUILD_3_5"
                    buildUsing = BUILDTOOL.MSBUILD_3_5
                Case "VS2008"
                    buildUsing = BUILDTOOL.VS2008
                Case "VS2005"
                    buildUsing = BUILDTOOL.VS2005
                Case "VS2003"
                    buildUsing = BUILDTOOL.VS2003
                Case Else
                    buildUsing = BUILDTOOL.AUTOSELECT
            End Select
        End If

        'Setup the build tool custom location (if exists), when it is not installed in the default location
        If (buildtoolLocation <> String.Empty) Then
            If File.Exists(buildtoolLocation) Then
                Select Case buildUsing
                    Case BUILDTOOL.VS2003
                        DEVENV_VS2003 = buildtoolLocation
                    Case BUILDTOOL.VS2005
                        DEVENV_VS2005 = buildtoolLocation
                    Case BUILDTOOL.VS2008
                        DEVENV_VS2008 = buildtoolLocation
                    Case BUILDTOOL.MSBUILD_2_0
                        MSBUILD_2_0 = buildtoolLocation
                    Case BUILDTOOL.MSBUILD_3_5
                        MSBUILD_3_5 = buildtoolLocation
                End Select
            Else
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR !  Unable to find build tool : " + buildtoolLocation + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find build tool : " + buildtoolLocation)
                End If
                WriteLog("Setup() ERROR ! Unable to find build tool : " + buildtoolLocation)
                setupOk = False
            End If
        End If

        'Setup the buildtool to be used on Failure
        Select Case onFailureTryWith
            Case "MSBUILD", "MSBUILD_2_0"
                onFailureBuildUsing = BUILDTOOL.MSBUILD_2_0
            Case "MSBUILD_3_5"
                onFailureBuildUsing = BUILDTOOL.MSBUILD_3_5
            Case "VS2008"
                onFailureBuildUsing = BUILDTOOL.VS2008
            Case "VS2005"
                onFailureBuildUsing = BUILDTOOL.VS2005
            Case "VS2003"
                onFailureBuildUsing = BUILDTOOL.VS2003
            Case Else
                onFailureBuildUsing = BUILDTOOL.NONE
        End Select

        'Check if the selected build tool is available
        If (buildUsing = BUILDTOOL.VS2003) Then
            If Not File.Exists(DEVENV_VS2003) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to find DEVENV " + DEVENV_VS2003 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2003, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2003)
                setupOk = False
            End If
        End If

        If (buildUsing = BUILDTOOL.VS2005) Then
            If Not File.Exists(DEVENV_VS2005) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to find DEVENV " + DEVENV_VS2005 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2005, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2005)
                setupOk = False
            End If
        End If

        If (buildUsing = BUILDTOOL.VS2008) Then
            If Not File.Exists(DEVENV_VS2008) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to find DEVENV " + DEVENV_VS2008 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2008, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2008)
                setupOk = False
            End If
        End If

        If (buildUsing = BUILDTOOL.MSBUILD_2_0) Then
            If Not File.Exists(MSBUILD_2_0) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to find MSBUILD 2.0: " + MSBUILD_2_0 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find MSBUILD 2.0: " + MSBUILD_2_0, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find MSBUILD 2.0: " + MSBUILD_2_0)
                setupOk = False
            End If
        End If

        If (buildUsing = BUILDTOOL.MSBUILD_3_5) Then
            If Not File.Exists(MSBUILD_3_5) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to find MSBUILD 3.5: " + MSBUILD_3_5 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find MSBUILD 3.5: " + MSBUILD_3_5, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find MSBUILD 3.5: " + MSBUILD_3_5)
                setupOk = False
            End If
        End If

        If (buildUsing = BUILDTOOL.AUTOSELECT) Then
            'When build tool to be used is set to AUTOSELECT, UBuild assumes there are projects in v1.1 and v2.0
            'For projects in v2.0 and above it builds using VS2005 while for v1.1 it uses VS2003
            If Not File.Exists(DEVENV_VS2003) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Buildtool = AUTO; Unable to find DEVENV " + DEVENV_VS2003 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2003, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2003)
                setupOk = False
            End If
            If Not File.Exists(DEVENV_VS2005) Then
                If dispXMLoutput Then
                    Output("<step name=""Setup"" status=""error"" >ERROR ! Buildtool = AUTO; Unable to find DEVENV " + DEVENV_VS2005 + "</step>")
                Else
                    Output("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2005, ConsoleTools.ConsoleColor.red)
                End If
                WriteLog("Setup() ERROR ! Unable to find DEVENV " + DEVENV_VS2005)
                setupOk = False
            End If
        End If

        If Not Directory.Exists(projectLocation) Then
            If dispXMLoutput Then
                Output("<step name=""Setup"" status=""error"" >ERROR ! Unable to locate project location : " + projectLocation + "</step>")
            Else
                Output("Setup() ERROR ! Unable to locate project location : " + projectLocation, ConsoleTools.ConsoleColor.red)
            End If
            WriteLog("ERROR ! Unable to find the project location : " + projectLocation)
            setupOk = False
        End If

        'Create the destination deployment directory structure
        Dim en As IDictionaryEnumerator
        en = htCopyTo.GetEnumerator
        While en.MoveNext
            If Not Directory.Exists(CType(en.Value, String)) Then
                Directory.CreateDirectory(CType(en.Value, String))
            End If
        End While

        'Creating logfile directories - <LogFileDirectory> Specific to ver 2.0+ i.e. building with MSBuild
        If String.Compare(logFileDir, String.Empty) <> 0 Then

            If Not Directory.Exists(logFileDir) Then
                Directory.CreateDirectory(logFileDir)
            End If

            logFileDirError = logFileDir + ERROR_DIR

            If Not Directory.Exists(logFileDirError) Then
                Directory.CreateDirectory(logFileDirError)
            End If

            'Set up the single error logfile for MSBuild
            UBuildSingleMsbuildErrorLogFile = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_MSBUILD_SINGLEERRORLOG_FILENAME + "-" + timestamp + FILEEXT_XML

            If File.Exists(UBuildSingleMsbuildErrorLogFile) Then
                File.Delete(UBuildSingleMsbuildErrorLogFile)
            End If
            sw = File.CreateText(UBuildSingleMsbuildErrorLogFile)
            If blUseStylesheetForErrorLogs Then
                sw.WriteLine("<?xml-stylesheet href='" + AddForwardSlashAtTheEnd(StyleSheetLocation) + UBUILD_MSBUILD_SINGLEERRORLOG_FILENAME_STYLESHEET + "' type='text/xsl'?><BuildErrors buildname=" + """" + buildname + """" + "><MSBuilds></MSBuilds></BuildErrors>")
            Else
                sw.WriteLine("<BuildErrors buildname=" + """" + buildname + """" + "><MSBuilds></MSBuilds></BuildErrors>")
            End If
            sw.Close()
            sw = Nothing

            'Set up the UBuild Error Detail file - This will contain detail information about files causing the build failure
            UBuildErrorDetailFile = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_ERR_DETAIL + "-" + timestamp + FILEEXT_XML

            If File.Exists(UBuildErrorDetailFile) Then
                File.Delete(UBuildErrorDetailFile)
            End If
            sw = File.CreateText(UBuildErrorDetailFile)
            If blUseStylesheetForErrorLogs Then
                sw.WriteLine("<?xml-stylesheet href='" + AddForwardSlashAtTheEnd(StyleSheetLocation) + UBUILD_ERR_DETAIL_STYLESHEET + "' type='text/xsl'?><BuildErrors buildname=" + """" + buildname + """" + "></BuildErrors>")
            Else
                sw.WriteLine("<BuildErrors buildname=" + """" + buildname + """" + "></BuildErrors>")
            End If
            sw.Close()
            sw = Nothing
        Else

            'Since logFileDir does not exists, set it to default location
            logFileDir = UBUILD_LOG_DEFAULT_LOCATION

            'Set up the logFileDirError directory
            logFileDirError = logFileDir + ERROR_DIR

            If Not Directory.Exists(logFileDirError) Then
                Directory.CreateDirectory(logFileDirError)
            End If

        End If


        'Create the XML log file for displaying projects informaiton e.g. Unused references, web-references etc
        Dim projectinfologfilexml As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_PROJECTINFO_LOG_FILENAME_XML
        'XML log file
        If File.Exists(projectinfologfilexml) Then
            File.Delete(projectinfologfilexml)
        End If
        sw = File.CreateText(projectinfologfilexml)
        sw.WriteLine("<?xml version=""1.0"" encoding=""UTF-8""?>")
        If blUseStylesheetForErrorLogs Then
            sw.WriteLine("<?xml-stylesheet href='" + AddForwardSlashAtTheEnd(StyleSheetLocation) + UBUILD_PROJECTINFO_STYLESHEET + "' type='text/xsl'?>")
        End If
        sw.WriteLine("<ProjectsInfo>")
        sw.WriteLine("</ProjectsInfo>")
        sw.Close()

        'Check if <DisplayUnusedReferences> is true and create the logfile. If already exists, delete and create
        If bldispUnusedReferences Then
            Dim unusedreflogfile As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_UNUSEDREF_LOG_FILENAME
            'TXT log file
            If txtLogFileMode = TEXTLOGFILEMODE.CREATE Then
                If File.Exists(unusedreflogfile) Then
                    File.Delete(unusedreflogfile)
                End If
                sw = File.CreateText(unusedreflogfile)
                sw.Close()
            ElseIf txtLogFileMode = TEXTLOGFILEMODE.APPEND Then
                If Not File.Exists(unusedreflogfile) Then
                    sw = File.CreateText(unusedreflogfile)
                    sw.Close()
                End If
            End If
            sw = Nothing
        End If

        'If <DisplayWebReferences> is True, then delete and re-create the .txt log file
        If bldispWebReferences Then
            Dim fs As FileStream
            Dim webreflogfile As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_WEBREFERENCES_LOG_FILENAME
            If File.Exists(webreflogfile) Then
                File.Delete(webreflogfile)
            End If
            fs = File.Create(webreflogfile)
            fs.Close()
            fs = Nothing
        End If

        'Check if the logger dll information is available
        If String.Compare(loggerName, String.Empty) <> 0 AndAlso File.Exists(loggerName) AndAlso String.Compare(loggerType, String.Empty) <> 0 Then
            'Logger information OK
            loggerInfo = True
        Else
            If dispXMLoutput Then
                Output("<step name=""Setup"" status=""warning"">Logger information " + loggerName + " not available. MSBuild Log files will not be generated </step>", ConsoleTools.ConsoleColor.yellow)
            Else
                Output("[Warning] Logger information " + loggerName + " not available. MSBuild Log files will not be generated", ConsoleTools.ConsoleColor.yellow)
            End If
        End If

        'Check if <VersionControlFileLocation> directory exists or not and create if necessary
        If Not Directory.Exists(BuildVersionControlFileLocation) Then
            Directory.CreateDirectory(BuildVersionControlFileLocation)
        End If

        'Get the proxy assemblies
        GetProxies()

        If setupOk Then
            WriteLog("Build Started ... " + startTime.ToString) 'The log file gets reated only after a successful setup
            WriteLog("Setup Successful...")
            If dispXMLoutput Then Output("<step name=""Setup"">Setup Successful</step>")
        End If

        Return setupOk
    End Function

    Private Sub DisplayUsage(ByVal msg As String)
        Output(msg)
        Output("Usage: nubuild /config configfile")
    End Sub

#End Region

#Region "Load Projects"

    Private Sub LoadProjects(ByVal projtype As String)
        Dim reader As XmlTextReader
        Dim objfs As New FileSearch
        Dim objfsln As New FileSearch
        Dim totFiles As Integer
        Dim indx As Integer
        Dim fi As FileInfo
        Dim fisln As FileInfo
        'Dim fs As StreamWriter
        Dim assmbly As String = ""
        Dim outputType As String = ""
        Dim FileExtension As String = String.Empty
        Dim projectguid As String = String.Empty

        objfs.Search(New DirectoryInfo(projectLocation), projtype)

        totFiles = objfs.Files.Count

        For indx = 0 To totFiles - 1
            fi = CType(objfs.Files.Item(indx), FileInfo)


            objfsln.Files.Clear()

            objfsln.Search(fi.Directory, "*.sln")

            If objfsln.Files.Count > 0 Then
                Dim slnlst As New ArrayList
                For j As Integer = 0 To objfsln.Files.Count - 1
                    fisln = CType(objfsln.Files.Item(j), FileInfo)
                    slnlst.Add(fisln.FullName)
                Next
                If Not ProjectSolutionFiles.Contains(fi.FullName) Then
                    ProjectSolutionFiles.Add(fi.FullName, slnlst)
                End If
            End If

            Dim projectname As String = fi.FullName.ToLower

            If Not ProjectDirectoryInfo.Contains(projectname) Then
                ProjectDirectoryInfo.Add(projectname, fi.Directory)
            End If

            projectguid = ""

            If GetDotNetVersion(projectname) = DOTNETVERSION.TWO Then

                If Not htProjectVersion.Contains(projectname) Then
                    htProjectVersion.Add(projectname, "2.0")
                End If

                Dim xmldoc As XmlDocument = New XmlDocument
                Try
                    xmldoc.Load(projectname)

                    projectguid = xmldoc.GetElementsByTagName("ProjectGuid").Item(0).InnerText()
                    assmbly = xmldoc.GetElementsByTagName("AssemblyName").Item(0).InnerText()
                    outputType = xmldoc.GetElementsByTagName("OutputType").Item(0).InnerText()

                    'HACK: To identify if the project is a web service or not
                    If ProjectDirectoryInfo.Contains(projectname) Then
                        Dim projdirinfo As DirectoryInfo = DirectCast(ProjectDirectoryInfo(projectname), DirectoryInfo)
                        If projdirinfo.Parent.Name.ToLower.Equals("web services") Then
                            If Not WebSvcProjects.Contains(projectname) Then
                                WebSvcProjects.Add(projectname)
                            End If
                        End If
                    End If

                    If Not outputType Is Nothing Then
                        Select Case outputType.ToLower
                            Case "winexe", "exe"
                                FileExtension = "exe"
                            Case "library"
                                FileExtension = "dll"
                        End Select

                        If Not htOutputType.Contains(projectname) Then
                            htOutputType.Add(projectname, FileExtension)
                        End If

                    End If

                    If Not htProjGuidAssmb.Contains(projectguid) Then
                        htProjGuidAssmb.Add(projectguid, assmbly)
                    Else
                        'Console.WriteLine("Examining project : " + fi.FullName + " - Found duplicate project GUID : " + projectguid + " Exisitng project(assmebly)  with same GUID : " + CType(htProjGuidAssmb(projectguid), String))
                        WriteLog("Examining project : " + fi.FullName + " - Found duplicate project GUID : " + projectguid + " Exisitng project(assmebly)  with same GUID : " + CType(htProjGuidAssmb(projectguid), String))
                    End If

                    If assmbly.Length > 0 And Not assmbly Is Nothing Then
                        If Not AllProjects.Contains(assmbly + "." + FileExtension) Then
                            AllProjects.Add(assmbly + "." + FileExtension, projectname)
                        End If

                        If Not ProjectsToAssmb.Contains(projectname) Then
                            ProjectsToAssmb.Add(projectname, assmbly + "." + FileExtension)
                        End If
                    End If

                Catch ex As Exception
                    Output("Failed to load project " + projectname + " ... [Continue]", ConsoleTools.ConsoleColor.red)
                End Try

            Else 'DOTNET_VER=1.0

                If Not htProjectVersion.Contains(projectname) Then
                    htProjectVersion.Add(projectname, "1.0")
                End If

                'HACK: To identify if the project is a web service or not
                If ProjectDirectoryInfo.Contains(projectname) Then
                    Dim projdirinfo As DirectoryInfo = DirectCast(ProjectDirectoryInfo(projectname), DirectoryInfo)
                    If projdirinfo.Parent.Name.ToLower.Equals("web services") Then
                        If Not WebSvcProjects.Contains(projectname) Then
                            WebSvcProjects.Add(projectname)
                        End If
                    End If
                End If

                reader = New XmlTextReader(projectname)

                While reader.Read

                    assmbly = reader.GetAttribute("AssemblyName")
                    outputType = reader.GetAttribute("OutputType")
                    projectguid = reader.GetAttribute("Project")

                    If Not outputType Is Nothing Then
                        Select Case outputType
                            Case "WinExe", "Exe"
                                FileExtension = "exe"
                            Case "Library"
                                FileExtension = "dll"
                        End Select

                        If Not htOutputType.Contains(projectname) Then
                            htOutputType.Add(projectname, FileExtension)
                        End If

                    End If

                    If reader.Name.Equals("Reference") AndAlso Not projectguid Is Nothing AndAlso Not assmbly Is Nothing AndAlso String.Compare(projectguid, String.Empty) <> 0 Then
                        If Not htProjGuidAssmb.Contains(projectguid) Then
                            htProjGuidAssmb.Add(projectguid, assmbly)
                        Else
                            WriteLog("Examining project : " + fi.FullName + " - Found duplicate project GUID : " + projectguid + " Exisitng project(assmebly)  with same GUID : " + CType(htProjGuidAssmb(projectguid), String))
                        End If
                    End If

                    If reader.Name.Equals("Settings") And Not assmbly Is Nothing Then
                        If Not AllProjects.Contains(assmbly + "." + FileExtension) Then
                            AllProjects.Add(assmbly + "." + FileExtension, projectname)
                        End If

                        If Not ProjectsToAssmb.Contains(projectname) Then
                            ProjectsToAssmb.Add(projectname, assmbly + "." + FileExtension)
                        End If

                    End If
                End While

                reader.Close()
                reader = Nothing

            End If

        Next

    End Sub

    Private Sub LoadAllProjectsLocation()
        If dispXMLoutput Then
            Output("<step name=""LoadAllProjs"">Loading all available projects</step>")
        Else
            Output("Loading all available projects...")
        End If
        'Log
        WriteLog("Loading all available projects...")
        LoadProjects("*.vbproj")
        LoadProjects("*.csproj")
    End Sub

    Private Sub LoadProjectsToBuildLocation()

        'Dim totFiles As Integer
        'Dim indx As Integer
        'Dim fi As FileInfo
        'Dim fs As StreamWriter
        Dim assmbly As String = ""
        Dim outputType As String = ""
        Dim outputPath As String = "bin\"
        'Dim tmparr() As String
        'Dim projname As String
        'Dim FileExtension As String
        'Dim projectguid As String


        If dispXMLoutput Then
            Output("<step name=""LoadProjsToBuild"">Loading projects to build</step>")
        Else
            Output("Loading projects to build ...")
        End If

        'Log
        WriteLog("Loading projects to build ...")

        If buildAllProjects Then
            'Create a temporary xml file containing all the projects to build - projBuildList

            If Not Directory.Exists("C:\temp") Then
                Directory.CreateDirectory("C:\temp")
            End If

            projBuildList = "C:\temp\projectstobuild.xml"

            'Delete the temporary file
            If File.Exists(projBuildList) Then
                File.Delete(projBuildList)
            End If

            Dim writer As XmlTextWriter = New XmlTextWriter(projBuildList, Nothing)
            writer.WriteStartDocument()
            writer.WriteStartElement("ProjectsToBuild")

            Dim ien As IDictionaryEnumerator = AllProjects.GetEnumerator
            While ien.MoveNext
                Dim _proj As String = CType(ien.Value, String)
                writer.WriteStartElement("Project")
                writer.WriteString(_proj)
                writer.WriteEndElement()
            End While

            writer.WriteEndElement()
            writer.WriteEndDocument()
            writer.Close()

        End If

        'Build projects provided in the list
        Dim xmldoc As XmlDocument = New XmlDocument
        xmldoc.Load(projBuildList)

        Dim xnl As XmlNodeList = xmldoc.GetElementsByTagName("Project")

        For Each xelement As XmlElement In xnl
            If File.Exists(xelement.InnerText) Then
                If xelement.HasAttributes Then
                    Dim copyto As String = xelement.GetAttribute("copyto").ToLower
                    If Not copyto Is Nothing And htCopyTo.Contains(copyto) And Not htCopyAssmbTo.Contains(xelement.InnerText) Then
                        htCopyAssmbTo.Add(xelement.InnerText.ToLower, CType(htCopyTo(copyto), String))
                    End If
                    If Not copyto Is Nothing And htCopyTo.Contains(copyto) And Not htDeployProjectsToBuild.Contains(copyto) Then
                        htDeployProjectsToBuild.Add(xelement.InnerText.ToLower, copyto)
                    End If
                End If
                AddToProjectsToBuildList(xelement.InnerText.ToLower)
            End If
        Next

        'At this point make a copy of the original list of projects to build provided by the user. 
        'Usage: If we want to build only  the ancestors of specific projects we can make use of this list

        Dim dicen As IDictionaryEnumerator
        dicen = ProjectsToBuildList.GetEnumerator
        While dicen.MoveNext
            If Not lstProjsToBuild.Contains(CType(dicen.Key, String)) Then
                lstProjsToBuild.Add(CType(dicen.Key, String), CType(dicen.Value, String))
            End If
        End While


        xmldoc = Nothing

    End Sub

    Private Sub AddToProjectsToBuildList(ByVal proj As String)

        Dim reader As XmlTextReader
        'Dim fs As StreamWriter
        Dim assmbly As String = ""
        Dim outputType As String = ""
        Dim outputPath As String = "bin\"
        Dim projconfig As String = ""
        Dim tmparr() As String
        Dim projname As String
        Dim FileExtension As String = String.Empty

        'Re-synchornize the project source code
        'If reSyncCode Then
        '    ReSyncSource(proj)
        'End If

        'Make the project name all lower case
        proj = proj.ToLower

        tmparr = proj.Split("\"c)

        projname = tmparr(tmparr.Length - 1)

        If GetDotNetVersion(proj) = DOTNETVERSION.TWO Then

            Dim xmldoc As XmlDocument = New XmlDocument

            File.SetAttributes(proj, FileAttributes.Normal)

            xmldoc.Load(proj)

            projconfig = xmldoc.GetElementsByTagName("Configuration").Item(0).InnerText
            assmbly = xmldoc.GetElementsByTagName("AssemblyName").Item(0).InnerText
            outputType = xmldoc.GetElementsByTagName("OutputType").Item(0).InnerText

            'Check if the project is a web service
            'HACK:   To identify if the project is a web service or not, we check if the project directory structure includes 'Web Services'
            '              This means if there are web service projects in other locations, ti will not get identified. 
            If ProjectDirectoryInfo.Contains(proj) Then
                Dim projdirinfo As DirectoryInfo = DirectCast(ProjectDirectoryInfo(proj), DirectoryInfo)
                If projdirinfo.Parent.Name.ToLower.Equals("web services") Then
                    If Not WebSvcProjects.Contains(proj) Then
                        WebSvcProjects.Add(proj)
                    End If
                End If
            End If
            'If proj.IndexOf("web services") > 0 Then
            '    If Not WebSvcProjects.Contains(proj) Then
            '        WebSvcProjects.Add(proj)
            '    End If
            'End If

            'Update the output path of the assembly
            Dim oplist As XmlNodeList = xmldoc.GetElementsByTagName("OutputPath")
            For Each xelement As XmlElement In oplist
                xelement.InnerText = "bin\"
            Next

            xmldoc.Save(proj)
            xmldoc = Nothing

            File.SetAttributes(proj, FileAttributes.ReadOnly)

            If Not outputType Is Nothing Then
                Select Case outputType.ToLower
                    Case "winexe", "exe"
                        FileExtension = "exe"
                    Case "library"
                        FileExtension = "dll"
                End Select

                If Not htOutputType.Contains(proj) Then
                    htOutputType.Add(proj, FileExtension)
                End If

            End If

            If Not assmbly Is Nothing And Not outputPath Is Nothing Then
                If Not htOutputPath.Contains(assmbly + "." + FileExtension) Then
                    htOutputPath.Add(assmbly + "." + FileExtension, outputPath)
                End If
            End If

            If assmbly.Length > 0 And Not assmbly Is Nothing Then
                If Not ProjectsToBuildList.Contains(assmbly + "." + FileExtension) Then
                    ProjectsToBuildList.Add(assmbly + "." + FileExtension, proj)
                End If
            End If

        Else 'DOTNET_VER = 1.0

            reader = New XmlTextReader(proj)
            reader.Read()

            'Check if the project is a web service
            'HACK:  To identify if the project is a web service or not, we check if the project directory structure includes 'Web Services'
            '       This means if there are web service projects in other locations, it will not get identified. 
            If ProjectDirectoryInfo.Contains(proj) Then
                Dim projdirinfo As DirectoryInfo = DirectCast(ProjectDirectoryInfo(proj), DirectoryInfo)
                If projdirinfo.Parent.Name.ToLower.Equals("web services") Then
                    If Not WebSvcProjects.Contains(proj) Then
                        WebSvcProjects.Add(proj)
                    End If
                End If
            End If

            While reader.Read
                assmbly = reader.GetAttribute("AssemblyName")
                outputType = reader.GetAttribute("OutputType")

                If Not outputType Is Nothing Then
                    Select Case outputType
                        Case "WinExe", "Exe"
                            FileExtension = "exe"
                        Case "Library"
                            FileExtension = "dll"
                    End Select

                    If Not htOutputType.Contains(proj) Then
                        htOutputType.Add(proj, FileExtension)
                    End If
                End If

                If reader.Name.Equals("Settings") And Not assmbly Is Nothing Then

                    If Not ProjectsToBuildList.Contains(assmbly + "." + FileExtension) Then
                        ProjectsToBuildList.Add(assmbly + "." + FileExtension, proj)
                    End If

                    While Not reader.Name.Equals("Config")
                        reader.Read()
                    End While

                    outputPath = reader.GetAttribute("OutputPath")

                    If reader.Name.Equals("Config") And Not assmbly Is Nothing And Not outputPath Is Nothing Then
                        If Not htOutputPath.Contains(assmbly + "." + FileExtension) Then
                            htOutputPath.Add(assmbly + "." + FileExtension, outputPath)
                        End If
                    End If

                End If

            End While

            reader.Close()
            reader = Nothing

        End If


    End Sub

#End Region

#Region "Create Dependency Graph"

    Private Sub CreateCompleteDependencyGraphOfAllProjects()
        'Create dependency graph for all available projects
        Dim dicten As IDictionaryEnumerator
        dicten = AllProjects.GetEnumerator
        While dicten.MoveNext
            CreateDependencyGraphFromProjects(CType(dicten.Value, String), AllProjects)
        End While
    End Sub

    Private Sub CreateDependencyGraphFromProjects()

        If dispXMLoutput Then
            Output("<step name=""CreateDependencyGraph"">Creating and Loading Dependency Graph into memory</step>")
        Else
            Output("Creating and Loading Dependency Graph into memory ...")
        End If

        'Log
        WriteLog("Creating and Loading Dependency Graph into memory ...")

        'Build projects specified in the project to build list
        Dim xmldoc As XmlDocument = New XmlDocument
        xmldoc.Load(projBuildList)

        Dim xnl As XmlNodeList = xmldoc.GetElementsByTagName("Project")

        For Each xelement As XmlElement In xnl
            CreateDependencyGraphFromProjects(xelement.InnerText, ProjectsToBuildList)
        Next

    End Sub

    Private Sub CreateDependencyGraphFromProjects(ByVal loadproject As String, ByVal Projects As SortedList)

        Dim reader As XmlTextReader
        Dim objAssemblyNode As AssemblyNode
        Dim assmbly As String
        Dim outputType As String
        Dim alTreeNode As New ArrayList
        Dim FileExtension As String

        '"Creating and Loading Dependency Graph for the specified project into memory ..."

        If File.Exists(loadproject) Then

            curAssemblyName = ""
            FileExtension = ""
            outputType = ""

            If GetDotNetVersion(loadproject) = DOTNETVERSION.TWO Then

                Dim xmldoc As XmlDocument = New XmlDocument
                xmldoc.Load(loadproject)
                assmbly = xmldoc.GetElementsByTagName("AssemblyName").Item(0).InnerText
                outputType = xmldoc.GetElementsByTagName("OutputType").Item(0).InnerText
                xmldoc = Nothing

                Select Case outputType.ToLower
                    Case "winexe", "exe"
                        FileExtension = "exe"
                    Case "library"
                        FileExtension = "dll"
                End Select

                If assmbly.Length > 0 And Not ToBeExcluded(assmbly) Then
                    curAssemblyName = assmbly + "." + FileExtension

                    If Not alTreeNode.Contains(curAssemblyName) Then
                        alTreeNode.Add(curAssemblyName)
                    End If

                    If Not AssemblyList.Contains(curAssemblyName) Then
                        objAssemblyNode = New AssemblyNode(curAssemblyName)
                        AssemblyList.Add(curAssemblyName, objAssemblyNode)
                    End If

                    'If ProjectsToBuildList.Contains(curAssemblyName) Then
                    '    GetDependencyFromProject(curAssemblyName, CType(ProjectsToBuildList(curAssemblyName), String))
                    'End If

                    If Projects.Contains(curAssemblyName) Then
                        GetDependencyFromProject(curAssemblyName, CType(Projects(curAssemblyName), String), Projects)
                    End If

                End If

            Else 'DOTNET_VER = 1.0

                reader = New XmlTextReader(loadproject)
                While reader.Read

                    assmbly = reader.GetAttribute("AssemblyName")
                    outputType = reader.GetAttribute("OutputType")

                    If reader.Name.Equals("Settings") And Not assmbly Is Nothing And Not ToBeExcluded(assmbly) Then

                        Select Case outputType
                            Case "WinExe", "Exe"
                                FileExtension = "exe"
                            Case "Library"
                                FileExtension = "dll"
                        End Select

                        curAssemblyName = assmbly + "." + FileExtension

                        If Not alTreeNode.Contains(curAssemblyName) Then
                            alTreeNode.Add(curAssemblyName)
                        End If

                        If Not AssemblyList.Contains(curAssemblyName) Then
                            objAssemblyNode = New AssemblyNode(curAssemblyName)
                            AssemblyList.Add(curAssemblyName, objAssemblyNode)
                        End If

                        'If ProjectsToBuildList.Contains(curAssemblyName) Then
                        '    GetDependencyFromProject(curAssemblyName, CType(ProjectsToBuildList(curAssemblyName), String))
                        'End If

                        If Projects.Contains(curAssemblyName) Then
                            GetDependencyFromProject(curAssemblyName, CType(Projects(curAssemblyName), String), Projects)
                        End If

                    End If

                End While

                reader.Close()
                reader = Nothing

            End If
        End If

        'Display all the assemblies
        alTreeNode.Sort()


    End Sub

    Private Sub GetDependencyFromProject(ByVal parentAssmemblyName As String, ByVal parentAssmemblyProjectName As String, ByVal Projects As SortedList)

        Dim i As Integer
        Dim curChildAssemblyName As String
        Dim curChildAssemblyProjectName As String
        Dim curChildAssmb As AssemblyNode
        Dim ParentAssmbForCurChild As AssemblyNode
        Dim dependencies As New ArrayList
        Dim reader As XmlTextReader
        Dim FileExtension As String
        Dim assmbly As String = ""
        Dim outputType As String = ""
        Dim refassmbly As String = ""
        Dim projectguid As String = ""
        Dim missingAssemblies As New ArrayList

        Try

            If GetDotNetVersion(parentAssmemblyProjectName) = DOTNETVERSION.TWO Then

                UpdateHintPath(parentAssmemblyProjectName) 'This will take out all project refrences and replace them with assembly reference

                Dim xmldoc As XmlDocument = New XmlDocument
                xmldoc.Load(parentAssmemblyProjectName)

                assmbly = xmldoc.GetElementsByTagName("AssemblyName").Item(0).InnerText()
                outputType = xmldoc.GetElementsByTagName("OutputType").Item(0).InnerText()

                Dim xnl As XmlNodeList = xmldoc.GetElementsByTagName("Reference")

                For Each xelement As XmlElement In xnl
                    If xelement.HasChildNodes Then
                        If xelement.HasAttribute("Include") Then
                            refassmbly = xelement.GetAttribute("Include")
                            If InStr(refassmbly, ",") Then
                                refassmbly = refassmbly.Split(","c)(0)
                            End If
                            If Not refassmbly Is Nothing And Not ToBeExcluded(refassmbly) And Not dependencies.Contains(refassmbly + ".dll") Then
                                dependencies.Add(refassmbly + ".dll")
                                If AllProjects.Contains(refassmbly + "." + "dll") And Not ProjectsToBuildList.Contains(refassmbly + "." + "dll") Then
                                    missingAssemblies.Add(refassmbly + ".dll")
                                End If
                            End If
                        End If
                    End If
                Next

                xnl = xmldoc.GetElementsByTagName("ProjectReference")

                For Each xelement As XmlElement In xnl
                    If xelement.HasChildNodes Then
                        If xelement.HasAttribute("Include") Then
                            refassmbly = xelement.GetAttribute("Include")
                            If InStr(refassmbly, ",") Then
                                refassmbly = refassmbly.Split(","c)(0)
                            End If
                            If Not ToBeExcluded(refassmbly) And Not dependencies.Contains(refassmbly + ".dll") Then
                                dependencies.Add(refassmbly + ".dll")
                                If AllProjects.Contains(refassmbly + "." + "dll") And Not ProjectsToBuildList.Contains(refassmbly + "." + "dll") Then
                                    missingAssemblies.Add(refassmbly + ".dll")
                                End If
                            End If
                        End If
                    End If
                Next

                'Load Missing Assemblies
                For indx As Integer = 0 To missingAssemblies.Count - 1
                    blMissingDependency = True
                    strMissingDependency = CType(missingAssemblies(indx), String)
                    If Not dispXMLoutput Then
                        Output(parentAssmemblyName + ":")
                        Output(" -->[Loading] Missing Dependency ... " + strMissingDependency)
                    End If
                    AddToProjectsToBuildList(CType(AllProjects(strMissingDependency), String))
                    CreateDependencyGraphFromProjects(CType(AllProjects(strMissingDependency), String), Projects)
                Next

            Else 'DOTNET_VER=1.0

                reader = New XmlTextReader(parentAssmemblyProjectName)

                'Proceed to <Settings> element
                While Not reader.Name.Equals("Settings")
                    reader.Read()
                End While

                assmbly = reader.GetAttribute("AssemblyName")
                outputType = reader.GetAttribute("OutputType")

                If Not outputType Is Nothing Then
                    Select Case outputType
                        Case "WinExe", "Exe"
                            FileExtension = "exe"
                        Case "Library"
                            FileExtension = "dll"
                    End Select
                End If

                'Proceed to <References> element
                While Not reader.Name.Equals("Reference")
                    reader.Read()
                End While

                'Proceed to <Reference> element
                While reader.Read
                    If reader.Name.Equals("Reference") Then
                        assmbly = reader.GetAttribute("AssemblyName")
                        projectguid = reader.GetAttribute("Project")

                        If assmbly Is Nothing And Not projectguid Is Nothing Then
                            'If htAssmbProjGuid.Contains(projectguid) Then
                            '    assmbly = CType(htAssmbProjGuid(projectguid), String)
                            'End If
                            assmbly = reader.GetAttribute("Name")
                        End If

                        If Not assmbly Is Nothing And Not ToBeExcluded(assmbly) Then

                            dependencies.Add(assmbly + "." + "dll")

                            If Not ToBeExcluded(assmbly) And AllProjects.Contains(assmbly + "." + "dll") And Not ProjectsToBuildList.Contains(assmbly + "." + "dll") Then
                                blMissingDependency = True
                                strMissingDependency = assmbly + "." + "dll"
                                If Not dispXMLoutput Then
                                    Output(parentAssmemblyName + ":")
                                    Output(" -->[Loading] Missing Dependency ... " + strMissingDependency)
                                End If
                                AddToProjectsToBuildList(CType(AllProjects(assmbly + "." + "dll"), String))
                                CreateDependencyGraphFromProjects(CType(AllProjects(assmbly + "." + "dll"), String), Projects)
                            End If

                        End If
                    End If

                End While

                reader.Close()
                reader = Nothing

            End If


            If Not dependencies Is Nothing Then

                For i = 0 To dependencies.Count - 1

                    curChildAssemblyName = CType(dependencies(i), String)
                    curChildAssemblyProjectName = CType(ProjectsToBuildList(curChildAssemblyName), String)

                    If Not AssemblyList.ContainsKey(curChildAssemblyName) Then
                        AssemblyList.Add(curChildAssemblyName, New AssemblyNode(curChildAssemblyName))
                    End If

                    curChildAssmb = CType(AssemblyList.Item(curChildAssemblyName), AssemblyNode)
                    ParentAssmbForCurChild = CType(AssemblyList.Item(parentAssmemblyName), AssemblyNode)

                    curChildAssmb.AddParent(ParentAssmbForCurChild)
                    ParentAssmbForCurChild.AddChild(curChildAssmb)

                Next

            End If

        Catch ex As Exception
            Console.WriteLine("Exception in GetDependencyFromProject() :" + ex.Message)
        End Try
    End Sub

#End Region

#Region "Detect Cycle"

    Private Function DetectCircularDependency() As Boolean

        If dispXMLoutput Then
            Output("<step name=""DetectCircularDependency"">Checking for Circular Dependency</step>")
        Else
            Output("Checking for Circular Dependency ...")
        End If

        WriteLog("Checking for Circular Dependency...")

        Dim en As IDictionaryEnumerator = AssemblyList.GetEnumerator
        While en.MoveNext
            Dim curNodeName As String = CType(en.Key, String)
            If CType(AssemblyList.Item(curNodeName), AssemblyNode).NodeColor = AssemblyNode.NodeColorEnum.WHITE Then
                Visit(curNodeName)
            End If
        End While

        Return cycleDetected

    End Function

    Private Sub Visit(ByVal curAssmbNodeName As String)

        Dim objCurAssmbNode As AssemblyNode
        Dim objCurAssmbChildNode As AssemblyNode
        Dim en As IDictionaryEnumerator
        Dim CurAssmnNodeName As String

        If AssemblyList.Contains(curAssmbNodeName) Then

            objCurAssmbNode = CType(AssemblyList.Item(curAssmbNodeName), AssemblyNode)

            objCurAssmbNode.Visited = True
            objCurAssmbNode.NodeColor = AssemblyNode.NodeColorEnum.GRAY

            beingVisitedNodes.Add(curAssmbNodeName)

            en = objCurAssmbNode.GetChildAssemblies.GetEnumerator

            While en.MoveNext
                CurAssmnNodeName = CType(en.Key, String)
                objCurAssmbChildNode = CType(AssemblyList.Item(CurAssmnNodeName), AssemblyNode)

                If Not ToBeExcluded(CurAssmnNodeName) Then

                    If Not lstChildren.Contains(CurAssmnNodeName) Then
                        lstChildren.Add(CurAssmnNodeName)
                    End If

                    If objCurAssmbChildNode.NodeColor = AssemblyNode.NodeColorEnum.GRAY Then
                        'Cycle detected
                        cycleDetected = True
                        DisplayCycle()
                        Output(CurAssmnNodeName, ConsoleTools.ConsoleColor.red, True)
                        WriteLog(CurAssmnNodeName)
                    ElseIf objCurAssmbChildNode.NodeColor = AssemblyNode.NodeColorEnum.WHITE Then
                        Visit(CurAssmnNodeName)
                    End If

                End If

            End While

            objCurAssmbNode.NodeColor = AssemblyNode.NodeColorEnum.BLACK
            beingVisitedNodes.Remove(objCurAssmbNode.GetAssemblyName)

        End If

    End Sub

    Private Sub DisplayCycle()
        Dim nodecount As Integer = beingVisitedNodes.Count

        If nodecount > 0 Then

            If dispXMLoutput Then
                Output("<message loc=""detectcycle""><![CDATA[Cycle Detected ...]]></message>")
                Output("<message loc=""displaycycle""><![CDATA[")
            Else
                Output("[Cycle Detected]", ConsoleTools.ConsoleColor.yellow, True)
            End If

            For i As Integer = 0 To nodecount - 1
                If AllProjects.Contains(CType(beingVisitedNodes(i), String)) Then
                    Output(CType(beingVisitedNodes(i), String) + "-->", ConsoleTools.ConsoleColor.red, False)
                    WriteLog(CType(beingVisitedNodes(i), String) + "-->", False)
                End If
            Next

            If dispXMLoutput Then
                Output("]]></message>")
            End If

            beingVisitedNodes.RemoveAt(0)

        End If

    End Sub

#End Region

#Region "Manage Assembly Version"

    Private Sub ArchiveBuildVersionInfo()

        Try
            If File.Exists(BuildVersionInfoFile) Then
                File.Delete(BuildVersionInfoFile)
            End If

            Dim writer As XmlTextWriter = New XmlTextWriter(BuildVersionInfoFile, Nothing)
            writer.WriteStartDocument()

            writer.WriteStartElement("BuildIdenity")
            writer.WriteAttributeString("xmlns", "xsd", Nothing, "http://www.w3.org/2001/XMLSchema")
            writer.WriteAttributeString("xmlns", "xsi", Nothing, "http://www.w3.org/2001/XMLSchema-instance")

            writer.WriteStartElement("BuildNumber")
            writer.WriteString(BuildVersionInfo)
            writer.WriteEndElement()

            writer.WriteEndElement()

            writer.WriteEndDocument()

            writer.Close()
        Catch ex As Exception
            Output(ex.Message, ConsoleTools.ConsoleColor.red)
        End Try

    End Sub

    Private Sub LogStartTimestamp()
        If File.Exists(BuildVersionInfoFile) Then

            Dim xmldoc As XmlDocument = New XmlDocument
            xmldoc.Load(BuildVersionInfoFile)

            Dim starttimestampelement As XmlElement = xmldoc.SelectSingleNode("StartTimestamp")
            If starttimestampelement Is Nothing Then
                starttimestampelement = xmldoc.CreateElement("StartTimestamp")
            End If
            starttimestampelement.InnerText = CreateTimeStamp(startTime)
            xmldoc.DocumentElement.AppendChild(starttimestampelement)
            xmldoc.Save(BuildVersionInfoFile)
        End If
    End Sub

    Private Sub SetupBuildVersionNumber()

        Dim assmbRunningRevNumberFile As String
        Dim updatedAssemblyVer As String = String.Empty
        Dim currentAssemblyRevNumber As String = String.Empty
        Dim nextAssemblyRevNumber As String = String.Empty
        Dim reader As StreamReader
        Dim writer As StreamWriter
        Dim resetRevNumberFile As Boolean = False
        Dim _BuildVersionInfoFile As String = AddBackSlashAtTheEnd(BuildVersionControlFileLocation) & UBUILD_BUILDVERSIONINFO_FILENAME

        '1. 'Setup the location of control file as specified in the config file, for the running revision number 
        assmbRunningRevNumberFile = AddBackSlashAtTheEnd(BuildVersionControlFileLocation) & UBUILD_AUTOINCREMENT_BUILDVERSION_COUNTER_FILENAME

        '2. 'If need to reset the revision number to '0' then delete the control file - so that it will get created in the next 
        'step and revision number will start from 0
        If manageAssemblyVersion AndAlso File.Exists(assmbRunningRevNumberFile) And resetAssemblyRevNumber Then
            File.Delete(assmbRunningRevNumberFile)
        End If

        If manageAssemblyVersion AndAlso autoIncrementAssemblyRevNumber Then
            '3. 'If the control file does not exists, create it with '0' as the starting revision number
            If Not File.Exists(assmbRunningRevNumberFile) Then
                currentAssemblyRevNumber = "0"
                writer = New StreamWriter(assmbRunningRevNumberFile)
                writer.Write(currentAssemblyRevNumber)
                writer.Close()
            Else
                '4. Control file exists - So read the current revision number
                reader = New StreamReader(assmbRunningRevNumberFile)
                currentAssemblyRevNumber = reader.ReadToEnd
                reader.Close()
                'OOPS ! Problem - This ideally should not happen. Even if it happens, take care of the situation by re-setting the revision number to 0
                If currentAssemblyRevNumber = String.Empty AndAlso Not IsNumeric(currentAssemblyRevNumber) Then
                    currentAssemblyRevNumber = "0"
                End If
            End If
        End If

        '5. Get the current existing build number from <BuildVersionInfo> file in '<<VersionControlFileLocation>'
        If File.Exists(_BuildVersionInfoFile) Then

            Dim xmldoc As XmlDocument = New XmlDocument
            xmldoc.Load(_BuildVersionInfoFile)

            Dim buildnumberampelement As XmlElement = xmldoc.SelectSingleNode("//BuildNumber")
            If buildnumberampelement Is Nothing Then
                buildNumber = String.Empty
            Else
                buildNumber = buildnumberampelement.InnerText.Split("."c)(0)
            End If

            xmldoc = Nothing
        Else
            'Control files missing!!! - Reset the version number => New version numbers will not be generated with every build
            'Same effect as Step 7
            buildNumber = String.Empty
            currentAssemblyRevNumber = "0"
            resetRevNumberFile = True

            Dim _warningmsg As String = "The version control file [" & _BuildVersionInfoFile & "] missing!!! Build version number will be reset to 1"
            Output(_warningmsg, ConsoleTools.ConsoleColor.red)

            WriteLog(_warningmsg)

        End If

        '6. 'Get the new build number for today -  indicated by MMDD.
        newBuildNumber = GetNewBuildNumber()

        '7. 'If in Auto-Increment mode, compare if the current build number is same as the new build number for today. 
        'If not same i.e. the assembly was built on previous day, then re-create the control file and set the available build revision number to "0'
        If manageAssemblyVersion AndAlso autoIncrementAssemblyRevNumber And buildNumber <> String.Empty And String.Compare(buildNumber, newBuildNumber) <> 0 Then
            currentAssemblyRevNumber = "0"
            resetRevNumberFile = True
        End If

        '8. 'Check if we want to automatically increment the revision number for each build
        'Then format the build revision  to add 2-digit year value
        If manageAssemblyVersion Then
            If autoIncrementAssemblyRevNumber Then
                resetRevNumberFile = True
                nextAssemblyRevNumber = (CType(currentAssemblyRevNumber, Integer) + 1).ToString
                buildRevision = nextAssemblyRevNumber
                buildRevisionFormatted = buildRevision + Format(Now, "yy")
            Else
                resetRevNumberFile = False
                buildRevisionFormatted = Format(Now, "yyyy") '/fixed revision number indicated by 4-digit year
            End If
        End If

        '9. 'Save the next available revision number 
        'Delete the control file and re-create it with the next available revision number
        If manageAssemblyVersion AndAlso autoIncrementAssemblyRevNumber And resetRevNumberFile Then
            File.Delete(assmbRunningRevNumberFile)
            writer = New StreamWriter(assmbRunningRevNumberFile)
            writer.Write(buildRevision)
            writer.Close()
        End If

        '10. 'Update the BuildVersionInfo - for archiving purpose
        BuildVersionInfo = newBuildNumber + "." + buildRevisionFormatted

    End Sub

    Private Sub ManageAssemblyVersionNumbers(ByVal projfile As String)

        'For now will only work with VB.Net and C# projects. No customization allowed e.g. Major and Minor versions cannot be specified by user. 
        'Ideal situation And Format Is assumed
        'Example 1:
        ' Input -    <Assembly: AssemblyVersion("1.0.*")>
        ' Output - <Assembly: AssemblyVersion("1.0.MMDD.0")>
        'Example 2:
        ' Input -    <Assembly: AssemblyVersion("1.0.MMDD.0*")>
        ' Output - <Assembly: AssemblyVersion("1.0.MMDD.0")>       
        'Example 3:
        ' Input -    <Assembly: AssemblyVersion("2.5.*")>
        ' Output - <Assembly: AssemblyVersion("2.5.MMDD.0")>

        Dim assmbInfoContent As String
        Dim assmbInfoContentUpdated As String
        Dim asmbfileinfoname As String = String.Empty
        Dim assmbinfo As String
        Dim updatedAssemblyVer As String
        Dim vbproj As Boolean = True
        Dim reader As StreamReader
        Dim writer As StreamWriter
        Dim resetRevNumberFile As Boolean = False
        Dim foundAssemblyInfoFile As Boolean = True

        Dim tmparr() As String = projfile.Split("\"c)
        Dim projname As String = tmparr(tmparr.Length - 1)

        'Check to see whether it is a VB.Net or C# project adn set the AssemblyInfo file type accordingly
        If projname.EndsWith(".vbproj") Then
            assmbinfo = "AssemblyInfo.vb"
            vbproj = True
        Else
            assmbinfo = "AssemblyInfo.cs"
            vbproj = False
        End If

        'Search for the AssemblyInfo.vb OR  AssemblyInfo.vb file under the project directory.
        'Proceed only if there exisits only  one AssemblyInfo file
        Dim objfs As New FileSearch
        objfs.Search(New DirectoryInfo(projfile.Replace(projname, "")), assmbinfo)

        'Ideally, there should be exactly one AssemblyInfo file. If we find more than one, we simply update the version in all so that which ever is the correct one
        'will be picked up automatically
        If objfs.Files.Count > 0 Then

            For indx As Integer = 0 To objfs.Files.Count - 1

                'Get the AssemblyInfo file path
                Dim fi As FileInfo = DirectCast(objfs.Files.Item(indx), FileInfo)
                asmbfileinfoname = fi.FullName

                'Set up the search pattern
                Dim pattern As Regex = New Regex("[aA]ssembly:?\s*AssemblyVersion\(""(?<majorver>\d)+\.(?<minorver>\d+)\.((?<buildnumber>\d+)\.(?<buildrevision>\d+)|(?<auto>\*))""\)", RegexOptions.Compiled)

                'Read the complete content of the AssemblyInfo file
                reader = New StreamReader(asmbfileinfoname)
                assmbInfoContent = reader.ReadToEnd
                reader.Close()

                'Execute the patten match search
                Dim matches As MatchCollection = pattern.Matches(assmbInfoContent)

                'Check if there was a match and proceed accordingly
                If matches.Count > 0 Then

                    majorVer = matches(0).Groups("majorver").Value
                    minorVer = matches(0).Groups("minorver").Value
                    buildNumber = matches(0).Groups("buildnumber").Value
                    buildRevision = matches(0).Groups("buildrevision").Value
                    autobuildnumber = matches(0).Groups("auto").Value

                    If manageAssemblyVersion Then

                        If vbproj Then
                            updatedAssemblyVer = "Assembly:AssemblyVersion(""" + majorVer + "." + minorVer + "." + newBuildNumber + "." + buildRevisionFormatted + """)"
                        Else
                            updatedAssemblyVer = "assembly:AssemblyVersion(""" + majorVer + "." + minorVer + "." + newBuildNumber + "." + buildRevisionFormatted + """)"
                        End If

                        'Update the assemblyinfo file content
                        assmbInfoContentUpdated = Regex.Replace(assmbInfoContent, pattern.ToString, updatedAssemblyVer)

                        'Delete the current AssemblyInfo file -
                        'Note: Here the file is not checked out from source control. Instead it is made readonly and version# updated. This way
                        '          developers getting the latest project source code will still be workign normally. This way only the build process updates the version#
                        File.SetAttributes(asmbfileinfoname, FileAttributes.Normal)
                        File.Delete(asmbfileinfoname)

                        'Recreate the AssemblyInfo file with the update content and save it
                        writer = New StreamWriter(asmbfileinfoname)
                        writer.WriteLine(assmbInfoContentUpdated)
                        writer.Close()

                        'Make the file read only
                        File.SetAttributes(asmbfileinfoname, FileAttributes.ReadOnly)

                    End If

                End If '//Check if there are any pattern matches i.e. matches.Count > 0

            Next
        Else
            foundAssemblyInfoFile = False
        End If

        'If could find the AssemblyInfo file then Exit sub 
        If Not foundAssemblyInfoFile Then
            WriteLog("[CAUTION] Could not find the " + asmbfileinfoname + "! Build Number might randomly generated")
            If dispXMLoutput Then
                Output("<message loc=""manageassemblyversion""><![CDATA[Could not find the " + asmbfileinfoname + "! Build Number will be randomly generated]]></message>")
            Else
                Output(" [CAUTION] Could not find the " + asmbfileinfoname + "! Build Number will be randomly generated", ConsoleTools.ConsoleColor.purple)
            End If
            Exit Sub
        End If

    End Sub

    Private Function GetNewBuildNumber() As String
        Dim m As Integer
        Dim d As Integer
        Dim strMonth As String
        Dim strDayOfMonth As String
        Dim buildNumber As String

        m = Now.Date.Month
        d = Now.Date.Day

        'Pad 0's to single digit month
        If m > 0 And m < 9 Then
            strMonth = "0" + m.ToString
        Else
            strMonth = m.ToString
        End If

        'Pad 0's to single digit day
        If d > 0 And d < 9 Then
            strDayOfMonth = "0" + d.ToString
        Else
            strDayOfMonth = d.ToString
        End If

        'Build number - concat month + day
        buildNumber = strMonth + strDayOfMonth

        Return buildNumber

    End Function
#End Region

#Region "Build"

    Private Function GenerateBuildList(ByVal curAssmbNode As String, ByVal buildlst As ArrayList) As ArrayList

        Dim objCurAssmbNode As AssemblyNode
        Dim objCurAssmbChildNode As AssemblyNode
        Dim CurAssmnNodeName As String
        Dim assemblylistkey As String
        Dim htallProjectskey As String


        assemblylistkey = curAssmbNode
        htallProjectskey = curAssmbNode

        If (AssemblyList.Contains(curAssmbNode) OrElse ContainsKey(AssemblyList, curAssmbNode, assemblylistkey)) Then


            If Not buildlst.Contains(curAssmbNode) And (AllProjects.Contains(curAssmbNode) OrElse ContainsKey(AllProjects, curAssmbNode, htallProjectskey)) Then
                buildlst.Add(curAssmbNode)
            End If

            objCurAssmbNode = CType(AssemblyList.Item(assemblylistkey), AssemblyNode)

            objCurAssmbNode.Visited = True
            objCurAssmbNode.NodeColor = AssemblyNode.NodeColorEnum.GRAY

            Dim en As IDictionaryEnumerator = objCurAssmbNode.GetChildAssemblies.GetEnumerator

            While en.MoveNext
                CurAssmnNodeName = CType(en.Key, String)
                objCurAssmbChildNode = CType(AssemblyList.Item(CurAssmnNodeName), AssemblyNode)

                If Not ToBeExcluded(CurAssmnNodeName) Then
                    If objCurAssmbChildNode.NodeColor <> AssemblyNode.NodeColorEnum.GRAY Then
                        GenerateBuildList(CurAssmnNodeName, buildlst)
                    End If
                End If
            End While
            objCurAssmbNode.NodeColor = AssemblyNode.NodeColorEnum.BLACK
        End If

        Return buildlst

    End Function

    Private Sub GenerateBuildList()

        Dim en As IDictionaryEnumerator
        Dim assmNodeName As String

        If dispXMLoutput Then
            Output("<step name=""GenerateList"">Generating Build List</step>")
        Else
            Output(vbCrLf + "Generating Build List ...")
        End If

        'Log
        WriteLog("Generating Build List ...")

        ResetColorAndVisitedStatus()

        en = AssemblyList.GetEnumerator

        While en.MoveNext

            assmNodeName = CType(en.Key, String)

            If Not BuildList.Contains(assmNodeName) And ProjectsToBuildList.Contains(assmNodeName) Then
                BuildList.Add(assmNodeName)

                'Get the compiled assembly location of the project 
                SetupAssemblyLocation(CType(ProjectsToBuildList(assmNodeName), String), assmNodeName)
            End If

        End While

        CreateAndSortBuildListGraph()

    End Sub

    Private Sub CreateAndSortBuildListGraph()
        Dim en As IEnumerator
        Dim curAssmbNode As AssemblyNode

        en = BuildList.GetEnumerator
        While en.MoveNext
            If AssemblyList.Contains(en.Current) Then
                curAssmbNode = CType(AssemblyList(en.Current), AssemblyNode)
                If Not BuildListGraph.Contains(en.Current) Then
                    BuildListGraph.Add(en.Current, curAssmbNode)
                End If
            End If
        End While

        For i As Integer = 0 To BuildList.Count - 1
            If Not VisitedNodesForSortedBuildList.Contains(CType(BuildList(i), String)) Then
                SortBuildListGraph(CType(BuildList(i), String))
            End If
        Next

    End Sub

    Private Sub SortBuildListGraph(ByVal curAssmbNode As String)

        Dim objCurAssmbNode As AssemblyNode
        Dim objCurAssmbChildNode As AssemblyNode
        Dim en As IDictionaryEnumerator
        Dim CurAssmnNodeName As String

        If BuildListGraph.Contains(curAssmbNode) Then

            objCurAssmbNode = CType(AssemblyList.Item(curAssmbNode), AssemblyNode)

            objCurAssmbNode.Visited = True
            objCurAssmbNode.NodeColor = AssemblyNode.NodeColorEnum.GRAY

            en = objCurAssmbNode.GetChildAssemblies.GetEnumerator

            While en.MoveNext

                CurAssmnNodeName = CType(en.Key, String)

                If Not ToBeExcluded(CurAssmnNodeName) Then

                    objCurAssmbChildNode = CType(AssemblyList.Item(CurAssmnNodeName), AssemblyNode)

                    If objCurAssmbChildNode.NodeColor <> AssemblyNode.NodeColorEnum.GRAY Then
                        SortBuildListGraph(CurAssmnNodeName)
                    End If
                End If

            End While

            objCurAssmbNode.NodeColor = AssemblyNode.NodeColorEnum.BLACK

            If Not SortedBuildList.Contains(CType(ProjectsToBuildList(curAssmbNode), String)) Then
                SortedBuildList.Add(CType(ProjectsToBuildList(curAssmbNode), String))
            End If

            If Not VisitedNodesForSortedBuildList.Contains(curAssmbNode) Then
                VisitedNodesForSortedBuildList.Add(curAssmbNode)
            End If

        End If
    End Sub

    Private Sub DisplayBuildList()
        WriteLog("Displaying Build List...")
        If dispXMLoutput Then
            Output("<step name=""DisplayList"">Displaying Build List</step>")
            Output("<BuildList>")
        End If
        For i As Integer = 0 To SortedBuildList.Count - 1
            If dispXMLoutput Then
                Output("<projname>" + CType(SortedBuildList(i), String) + "</projname>")
            Else
                Output(CType(SortedBuildList(i), String), ConsoleTools.ConsoleColor.grey)
            End If

            WriteLog(CType(SortedBuildList(i), String))
        Next
        If dispXMLoutput Then Output("</BuildList>")
    End Sub

    Private Function DoParallelBuild() As Integer

        If dispXMLoutput Then
            Output("<step name=""Build"">Building Projects - in Parallel</step>")
            Output("<BuildProjects>")
        Else
            Output(vbCrLf + "Building Projects - in Parallel ...")
        End If

        'Log
        WriteLog("Building Projects - in Parallel ...")

        Dim projcount As Integer = -1

        NosOfProjectToBuild = SortedBuildList.Count

        Dim buckets As ArrayList = CreateBucketsForParallelBuild() 'This is the important part in doing parallel build

        For i As Integer = 0 To buckets.Count - 1

            Dim bucket As ArrayList = CType(buckets(i), ArrayList)

            For j As Integer = 0 To bucket.Count - 1

                projcount = projcount + 1

                NosOfParallelBuild = bucket.Count

                Dim projname As String = CType(bucket(j), String)

                Dim parallelbuildarg As ParallelBuildArgs = New ParallelBuildArgs

                parallelbuildarg.mProjName = projname
                parallelbuildarg.mProjectCount = projcount
                parallelbuildarg.StartParallelBuildDelegate = AddressOf ParallelBuild

                Dim t As New Thread(AddressOf parallelbuildarg.DoBuild)
                t.IsBackground = True
                t.Priority = ThreadPriority.Lowest
                t.Start()

            Next

            If Not blContinueOnFailure Then

                While (NosOfParallelBuild <> 0 And pllBuildStatusCd = 0)
                    'Spinlock Wait
                End While

                If pllBuildStatusCd = -1 Then
                    Exit For
                End If

            Else

                While (NosOfParallelBuild <> 0)
                    'Spinlock Wait
                End While

            End If

        Next

        'Display the log
        For j As Integer = 0 To ParallelBuildLog.Count - 1
            WriteLog(CType(ParallelBuildLog(j), String))
        Next

        If blAtLeastOneProjFailedInParalellBuild Then
            pllBuildStatusCd = -1
        End If

        Return pllBuildStatusCd

    End Function

    Private Sub ParallelBuild(ByVal projToBuild As String, ByVal projcount As Integer)


        Dim blSuccess As Boolean
        Dim totProjectsToBuild As Integer = SortedBuildList.Count
        'Dim percentComplete As Integer
        Dim assmbName As String = String.Empty
        'Dim buildStatusCd As Integer

        If Not dispXMLoutput Then Output(projToBuild, ConsoleTools.ConsoleColor.grey)

        If ProjectsToAssmb.Contains(projToBuild) Then
            assmbName = CType(ProjectsToAssmb(projToBuild), String)
        End If

        blSuccess = True

        'First check if we always want to build the project or not 
        If Not alwaysBuildProject Then
            'We don't want to always build the project - Check if already built and available. If yes, then skip building this project.
            If IsAlreadyBuilt(assmbName) Then
                'Output("Skipped build ... already available", ConsoleTools.ConsoleColor.yellow)
                BuildSkipped(projcount, projToBuild)
            Else
                'Build the project if it's not a proxy
                If IsProxy(assmbName) And Not buildProxyProjects Then
                    'Output("Skipped build ... This is a proxy. already available", ConsoleTools.ConsoleColor.yellow)
                    BuildSkipped(projcount, projToBuild, "This is a proxy. Already available")
                Else
                    blSuccess = BuildProject(projToBuild, totProjectsToBuild, projcount)
                End If
            End If
        Else
            'We always want to build the project, if it is not a proxy
            If IsProxy(assmbName) And Not buildProxyProjects Then
                'Output("Skipped build ... This is a proxy. already available", ConsoleTools.ConsoleColor.yellow)
                BuildSkipped(0, projToBuild, "This is a proxy. Already available")
            Else
                blSuccess = BuildProject(projToBuild, totProjectsToBuild, projcount)
            End If
        End If

        If dispXMLoutput Then Output("</BuildProjects>")

        'Send build status to notification server, if set up to do so
        If sendnotification Then
            SendBuildStatusToNotificationServer(UBuildErrorDetailFile)
        End If

        'Setup the build status code in a synchronized way
        Dim objLock As Object = New Object
        If blSuccess Then
            SyncLock objLock
                pllBuildStatusCd = 0
                NosOfParallelBuild = NosOfParallelBuild - 1
            End SyncLock
        Else
            SyncLock objLock
                blAtLeastOneProjFailedInParalellBuild = True
                pllBuildStatusCd = -1
                NosOfParallelBuild = NosOfParallelBuild - 1
            End SyncLock
        End If



    End Sub

    Private Function CreateBucketsForParallelBuild() As ArrayList

        Dim NewBuildList As ArrayList = New ArrayList
        Dim CurrentMultiThreadList As ArrayList

        CurrentMultiThreadList = New ArrayList
        NewBuildList.Add(CurrentMultiThreadList)

        For i As Integer = 0 To SortedBuildList.Count - 1

            Dim project_i As String = CType(SortedBuildList(i), String)
            Dim BuildList_Project_i As ArrayList = GenerateBuildList(CType(ProjectsToAssmb(project_i), String), New ArrayList)

            For j As Integer = 0 To BuildList_Project_i.Count - 1
                Dim project_j As String = CType(AllProjects(CType(BuildList_Project_i(j), String)), String)

                If CurrentMultiThreadList.Contains(project_j) Then
                    CurrentMultiThreadList = New ArrayList
                    NewBuildList.Add(CurrentMultiThreadList)
                    Exit For
                End If
            Next

            CurrentMultiThreadList.Add(project_i)

        Next

        Return NewBuildList

    End Function

    Private Function DoBuild() As Integer

        If dispXMLoutput Then
            Output("<step name=""Build"">Building Projects</step>")
            Output("<BuildProjects>")
        Else
            Output(vbCrLf + "Building Projects ...")
        End If

        'Log
        WriteLog("Building Projects ...")

        Dim blSuccess As Boolean
        Dim totProjectsToBuild As Integer = ProjectsToBuildList.Count
        'Dim percentComplete As Integer
        Dim assmbName As String = String.Empty
        Dim buildStatusCd As Integer

        For i As Integer = 0 To SortedBuildList.Count - 1

            Dim projToBuild As String = CType(SortedBuildList(i), String)

            If Not dispXMLoutput Then Output(projToBuild, ConsoleTools.ConsoleColor.grey)

            If ProjectsToAssmb.Contains(projToBuild) Then
                assmbName = CType(ProjectsToAssmb(projToBuild), String)
            End If

            blSuccess = True

            'First check if we always want to build the project or not 
            If Not alwaysBuildProject Then
                'We don't want to always build the project - Check if already built and available. If yes, then skip building this project.
                If IsAlreadyBuilt(assmbName) Then
                    'Output("Skipped build ... already available", ConsoleTools.ConsoleColor.yellow)
                    BuildSkipped(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                Else
                    'Build the project if it's not a proxy
                    If IsProxy(assmbName) And Not buildProxyProjects Then
                        'Output("Skipped build ... This is a proxy. already available", ConsoleTools.ConsoleColor.yellow)
                        BuildSkipped(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild, "This is a proxy. Already available")
                    Else
                        blSuccess = BuildProject(projToBuild, totProjectsToBuild, i)
                    End If
                End If
            Else
                'We always want to build the project, if it is not a proxy
                If IsProxy(assmbName) And Not buildProxyProjects Then
                    'Output("Skipped build ... This is a proxy. already available", ConsoleTools.ConsoleColor.yellow)
                    BuildSkipped(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild, "This is a proxy. Already available")
                Else
                    blSuccess = BuildProject(projToBuild, totProjectsToBuild, i)
                End If
            End If

            'Don't proceeed any further if the build failed for a project unless <ContinueOnFailure = TRUE>
            If Not blSuccess And Not blContinueOnFailure Then
                Exit For
            End If

        Next

        If dispXMLoutput Then Output("</BuildProjects>")

        'Send build status to notification server, if set up to do so
        If sendnotification Then
            SendBuildStatusToNotificationServer(UBuildErrorDetailFile)
        End If

        'Setup the buld status code
        If blSuccess Then
            buildStatusCd = 0
        Else
            buildStatusCd = -1
        End If

        'If ContinueOnFailure=TRUE and there is atleast one project failed, set status code to -1
        If blContinueOnFailure AndAlso blAtLeastOneProjFailedInBuild Then
            buildStatusCd = -1
        End If

        Return buildStatusCd

    End Function

    Private Function BuildProject(ByVal projToBuild As String, ByVal totProjectsToBuild As Integer, ByVal i As Integer) As Boolean

        Dim blSuccess As Boolean = True

        If Build(projToBuild, True, buildUsing) Then
            'Build - First try with the selected tool - SUCCESS :-)
            BuildSuccess(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
        Else
            'Build Failed ! - Check if need to retry the build using someother tool
            If onFailureBuildUsing <> BUILDTOOL.NONE Then

                If Build(projToBuild, True, onFailureBuildUsing) Then
                    'Build - Second Try with Alternative Tool - SUCCESS :-)
                    BuildSuccess(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                Else
                    'Build Failed - Second Try with Alternative Tool - Check if need to retry after deleting all .sln files
                    If onFailureDeleteSlnFileAndRebuild Then

                        If DeleteProjectSolutionFiles(projToBuild) Then
                            If Build(projToBuild, True, buildUsing) Then
                                'Build - Third Try after deleting the .sln files - SUCCESS :-)
                                BuildSuccess(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                            Else
                                'Project failed to build with both original build tool,alternative build tool and it also failed after deleting the .sln files - FAILED :-(
                                BuildFailed(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                                blSuccess = False
                            End If
                        Else
                            'Unable to delete .sln files and thus could not rebuild - FAILED :-(
                            BuildFailed(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                            blSuccess = False
                        End If
                    Else
                        'Project failed to build with both original build tool and alternative build tool
                        BuildFailed(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                        blSuccess = False
                    End If
                End If

            ElseIf onFailureDeleteSlnFileAndRebuild Then 'Check if need to retry (i.e. to re-build) after deleting all .sln files

                If DeleteProjectSolutionFiles(projToBuild) Then
                    If Build(projToBuild, True, buildUsing) Then
                        'Build - SUCCESS after deleting the .sln files :-)
                        BuildSuccess(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                    Else
                        'Project failed to build on the first try and there was no retry on failure option and it also failed after deleting the .sln files
                        BuildFailed(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                        blSuccess = False
                    End If
                Else
                    'Could not delete the .sln files and hence could not re-build
                    BuildFailed(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                    blSuccess = False
                End If
            Else
                'Project failed to build on the first try and there was no retry on failure (i) with different tool or (ii) rebuild after deleting .sln files option set
                BuildFailed(Math.Round(((i + 1) / totProjectsToBuild) * 100), projToBuild)
                blSuccess = False
            End If

        End If

        Return blSuccess
    End Function

    Private Function DeleteProjectSolutionFiles(ByVal projToBuild As String) As Boolean

        Dim slnFilesDeleted As Boolean = True
        Dim actualProjToBuild As String = String.Empty


        If ContainsKey(ProjectSolutionFiles, projToBuild, actualProjToBuild) Then
            Dim slnlst As ArrayList = DirectCast(ProjectSolutionFiles(actualProjToBuild), ArrayList)
            For index As Integer = 0 To slnlst.Count - 1
                Dim slnfile As String = CType(slnlst(index), String)
                If Not slnfile Is Nothing AndAlso String.Compare(slnfile, String.Empty, True) <> 0 AndAlso File.Exists(slnfile) Then
                    Try
                        File.SetAttributes(slnfile, FileAttributes.Normal)
                        File.Delete(slnfile)
                    Catch ex As Exception
                        slnFilesDeleted = False
                    End Try
                End If
            Next
        End If


        Return slnFilesDeleted

    End Function

    Private Sub BuildSuccess(ByVal percentComplete As String, ByVal projname As String)

        If blParallelBuild Then
            Dim objlock As Object = New Object
            SyncLock objlock
                NosOfProjectsBuiltSuccessfully = NosOfProjectsBuiltSuccessfully + 1
                percentComplete = Math.Round((NosOfProjectsBuiltSuccessfully / NosOfProjectToBuild) * 100)
            End SyncLock
        End If

        If dispXMLoutput Then
            Output("<project buildstatus=""Success"" buildmsg="""" percentcomplete=""" + percentComplete.ToString + "%"">" + projname + "</project>", ConsoleTools.ConsoleColor.green)
        Else
            Output(" [Success] - " + percentComplete.ToString + "%", ConsoleTools.ConsoleColor.green)
        End If
        'Log
        Dim logstmt As String = projname + " [Success] - " + percentComplete.ToString + "%"
        If blParallelBuild Then
            ParallelBuildLog.Add(logstmt)
        Else
            WriteLog(logstmt)
        End If

    End Sub

    Private Sub BuildFailed(ByVal percentComplete As String, ByVal projname As String)

        If blParallelBuild Then
            Dim objlock As Object = New Object
            SyncLock objlock
                NosOfProjectsBuiltSuccessfully = NosOfProjectsBuiltSuccessfully + 1
                percentComplete = Math.Round((NosOfProjectsBuiltSuccessfully / NosOfProjectToBuild) * 100)
            End SyncLock
        End If

        'Display build log in 'Notepad' if the build tool is a DEVENV
        If (buildUsing = BUILDTOOL.VS2003 OrElse buildUsing = BUILDTOOL.VS2005 OrElse buildUsing = BUILDTOOL.VS2008) AndAlso dispPopupBuildMsg Then
            DisplayErrMsgInNotePad(txtLogFileDir + UBUILD_OUTPUT_LOG_FILENAME)
        End If

        If dispXMLoutput Then
            Output("<project buildstatus=""[Failed]"" buildmsg=""" + glblBuildMsg + """ percentcomplete=""" + percentComplete.ToString + "%"">" + projname + "</project>", ConsoleTools.ConsoleColor.red)
        Else
            Output(" [Failed]  ", ConsoleTools.ConsoleColor.red)
        End If

        'Log
        Dim logstmt As String = projname + " [Failed] "
        If blParallelBuild Then
            ParallelBuildLog.Add(logstmt)
        Else
            WriteLog(logstmt)
        End If


        'Parse Errorlog file and display the error details
        If String.Compare(errorlogfilename, String.Empty) <> 0 And File.Exists(errorlogfilename) Then

            'Parse error log details and put it in one file
            If blParseUBuildErrorLog Then
                ParseUBuildErrorLog(errorlogfilename)
            End If

            If dispPopupBuildMsg Then
                DisplayErrMsgInNotePad(errorlogfilename)
            End If

        End If

    End Sub

    Private Sub BuildSkipped(ByVal percentComplete As String, ByVal projname As String, Optional ByVal skippedmsg As String = "Already available")

        If blParallelBuild Then
            Dim objlock As Object = New Object
            SyncLock objlock
                NosOfProjectsBuiltSuccessfully = NosOfProjectsBuiltSuccessfully + 1
                percentComplete = Math.Round((NosOfProjectsBuiltSuccessfully / NosOfProjectToBuild) * 100)
            End SyncLock
        End If

        If dispXMLoutput Then
            Output("<project buildstatus=""[Skipped]"" buildmsg=""" + skippedmsg + """ percentcomplete=""" + percentComplete.ToString + "%"">" + projname + "</project>", ConsoleTools.ConsoleColor.yellow)
        Else
            Output(" [Skipped]  " + skippedmsg + " - " + percentComplete.ToString + "%", ConsoleTools.ConsoleColor.yellow)
        End If
        'Log
        Dim logstmt As String = projname + " [Skipped] " + skippedmsg + "  " + percentComplete.ToString + "%"
        If blParallelBuild Then
            ParallelBuildLog.Add(logstmt)
        Else
            WriteLog(logstmt)
        End If
    End Sub

    Private Function Build(ByVal proj As String, ByVal copyToConfigAssmbLoc As Boolean, ByVal buildusing As BUILDTOOL) As Boolean
        Dim projuser As String
        Dim buildSuccess As Boolean
        Dim exitCode As Integer
        Dim p As Process
        Dim logFileName As String = txtLogFileDir + UBUILD_OUTPUT_LOG_FILENAME
        Dim psi As ProcessStartInfo = New ProcessStartInfo
        Dim DEVENV As String = ""
        Dim buildArg As String = ""
        Dim buildWithVersion As String = String.Empty


        'Re-set the value global build message to empty
        glblBuildMsg = ""

        'Create the log file. Remove .vbproj and .csproj extension and replace with .log. If already exists then delete
        Dim tmparr() As String = proj.Split("\"c)
        Dim logFileProjName As String = tmparr(tmparr.Length - 1)
        Dim orgprojname As String

        'Save the original project name
        orgprojname = logFileProjName

        'Create the name of the logfile for XMLLogger and the directory name for EXE deployment
        If InStr(logFileProjName, ".vbproj") Then
            logFileProjName = orgprojname.Replace(".vbproj", ".log")
        End If
        If InStr(logFileProjName, ".csproj") Then
            logFileProjName = orgprojname.Replace(".csproj", ".log")
        End If

        'Setup the build tool and the arguments
        If buildusing = BUILDTOOL.AUTOSELECT Then
            If GetDotNetVersion(proj) = DOTNETVERSION.TWO Then
                DEVENV = DEVENV_VS2005
                buildArg = " /" + buildType + " " + buildConfig + " " + """" + proj + """" + "  /out " + logFileName
            Else
                DEVENV = DEVENV_VS2003
                buildArg = " /" + buildType + " " + buildConfig + " " + """" + proj + """" + "  /out " + logFileName
            End If
        ElseIf buildusing = BUILDTOOL.MSBUILD_2_0 Then
            logFileName = logFileDir + "UBuild." + logFileProjName + ".xml"
            DEVENV = MSBUILD_2_0
            If loggerInfo Then
                buildArg = """" + proj + """" + " /t:" + buildType + " /p:Configuration=" + buildConfig.Trim + " /v:m /l:" + loggerType + "," + """" + loggerName + """" + ";" + """" + logFileName + """"
            Else
                buildArg = """" + proj + """" + " /t:" + buildType + " /p:Configuration=" + buildConfig.Trim
            End If
        ElseIf buildusing = BUILDTOOL.MSBUILD_3_5 Then
            logFileName = logFileDir + "UBuild." + logFileProjName + ".xml"
            DEVENV = MSBUILD_3_5
            If String.Compare(targetFrameworkVersion, String.Empty) = 0 Then
                buildWithVersion = "v2.0 "
            Else
                buildWithVersion = targetFrameworkVersion
            End If
            If loggerInfo Then
                buildArg = """" + proj + """" + " /t:" + buildType + " /p:Configuration=" + buildConfig.Trim + ";TargetFrameworkVersion=" + buildWithVersion + " /v:m /l:" + loggerType + "," + """" + loggerName + """" + ";" + """" + logFileName + """"
            Else
                buildArg = """" + proj + """" + " /t:" + buildType + " /p:Configuration=" + buildConfig.Trim + ";TargetFrameworkVersion=" + buildWithVersion
            End If
        ElseIf buildusing = BUILDTOOL.VS2008 Then
            DEVENV = DEVENV_VS2008
            buildArg = " /" + buildType + " debug " + """" + proj + """" + "  /out " + logFileName
        ElseIf buildusing = BUILDTOOL.VS2005 Then
            DEVENV = DEVENV_VS2005
            buildArg = " /" + buildType + " debug " + """" + proj + """" + "  /out " + logFileName
        ElseIf buildusing = BUILDTOOL.VS2003 Then
            DEVENV = DEVENV_VS2003
            buildArg = " /" + buildType + " debug " + """" + proj + """" + "  /out " + logFileName
        End If

        'Delete the logfile, if it exists
        'If File.Exists(logFileName) Then
        '    File.Delete(logFileName)
        'End If

        'Update the proect's user settings
        projuser = proj + ".user"

        If File.Exists(projuser) Then
            UpdateProjUserSettings(projuser, buildFileLocation)
        End If

        'For generating custom assembly version numbers
        If manageAssemblyVersion Then
            ManageAssemblyVersionNumbers(proj)
        End If

        'If <GenerateSerializationAssemblies> has a value of "On" or "Off"
        If setSgen Then
            SetupGenerateSerializationAssemblies(proj)
        End If

        'Check if building with MSBuild3.5 and <TargetFrameworkVersion> is set accordingly
        If buildusing = BUILDTOOL.MSBUILD_3_5 AndAlso String.Compare(targetFrameworkVersion, String.Empty) <> 0 AndAlso (String.Compare(targetFrameworkVersion, "v2.0", True) = 0 OrElse String.Compare(targetFrameworkVersion, "v3.0", True) OrElse String.Compare(targetFrameworkVersion, "v3.5", True)) Then
            SetupTargetFrameworkVersion(proj)
        End If

        If UpdateHintPath(proj) Then
            psi.FileName = """" + DEVENV + """"
            psi.WindowStyle = ProcessWindowStyle.Hidden
            psi.ErrorDialog = True
            psi.UseShellExecute = True
            psi.Arguments = buildArg

            p = Process.Start(psi)
            p.WaitForExit()
            exitCode = p.ExitCode
            p.Close()
            If exitCode <> 0 Then
                'Move the log files to \Error folder if using MSBUILD and logger info is available 
                If loggerInfo AndAlso (buildusing = BUILDTOOL.MSBUILD_2_0 OrElse buildusing = BUILDTOOL.MSBUILD_3_5) Then
                    If msBuildErrorLogsByDate Then
                        errorlogfilename = logFileDirError + "\" + "UBuild." + logFileProjName + "_" + Now.ToShortDateString.Replace("/", "") + FILEEXT_XML
                    Else
                        errorlogfilename = logFileDirError + "\" + "UBuild." + logFileProjName + FILEEXT_XML
                    End If
                    MoveMSBuildErrorLogs(logFileName, errorlogfilename)
                End If
                buildSuccess = False
                blAtLeastOneProjFailedInBuild = True
            Else
                buildSuccess = True
                'Detect unused references for this project
                If bldispUnusedReferences Then
                    DetectUnusedReferences(proj)
                End If
            End If

            'Proceed with deployment
            If exitCode = 0 And copyToConfigAssmbLoc Then
                If File.Exists(CType(BuildListMapProjToAssmbLoc(proj), String)) Then
                    buildSuccess = DoDeployment(proj)
                Else
                    'This means the project was skipped and not built
                    Output(" [Skipped Build] " + vbCrLf + " 1. Check if you are able to open the project in IDE properly " + vbCrLf + " 2. Try deleteing all .sln (and .webinfo if applicable) files from the project directory", ConsoleTools.ConsoleColor.yellow)
                    buildSuccess = False
                    blAtLeastOneProjFailedInBuild = True
                End If

            End If
        Else
            buildSuccess = False
            blAtLeastOneProjFailedInBuild = True
        End If

        Return buildSuccess
    End Function

#End Region

#Region "Deployment"

    'Private Function DoDeployment(ByVal proj As String) As Boolean

    '    Dim src As String
    '    Dim dest As String
    '    Dim deployDllTo As New ArrayList
    '    Dim buildSuccess As Boolean = True
    '    Dim orgprojname As String

    '    'Create the log file. Remove .vbproj and .csproj extension and replace with .log. If already exists then delete
    '    Dim tmparr() As String = proj.Split("\"c)
    '    Dim logFileProjName As String = tmparr(tmparr.Length - 1)
    '    Dim deployExeProjName As String = ""

    '    'Save the original project name
    '    orgprojname = logFileProjName

    '    'Create the directory name for EXE deployment
    '    If InStr(logFileProjName, ".vbproj") Then
    '        deployExeProjName = orgprojname.Replace(".vbproj", "")
    '    End If
    '    If InStr(logFileProjName, ".csproj") Then
    '        deployExeProjName = orgprojname.Replace(".csproj", "")
    '    End If

    '    '----------------------------------
    '    'if the project is a web service (output type will always be a DLL, so extra check not requried) and there is a <WebServices id="websvc"></WebService> tag
    '    ' in the config file, then setup deployment accordingly
    '    If htOutputType.Contains(proj) And WebSvcProjects.Contains(proj) And htCopyTo.Contains("websvc") Then

    '        Dim srcOutputDir As String
    '        Dim deployWebSvcProjLoc As String = AddBackSlashAtTheEnd(AddBackSlashAtTheEnd(CType(htCopyTo("websvc"), String)) + deployExeProjName)

    '        CleanOutputDir(deployWebSvcProjLoc)

    '        'Copy the folders specified by the "copydirs" attribute from src to dest
    '        If lstDeployWebSvcDir.Count > 0 Then
    '            For i As Integer = 0 To lstDeployWebSvcDir.Count - 1
    '                srcOutputDir = proj.Replace(orgprojname, CType(lstDeployWebSvcDir(i), String))
    '                CopyDirectory(srcOutputDir, deployWebSvcProjLoc)
    '                If dispXMLoutput Then
    '                    Output("<message loc=""builddeploy""><![CDATA[" + "Deployed Web Service Dir:" + srcOutputDir + " ==> " + deployWebSvcProjLoc + "]]></message>")
    '                End If
    '            Next
    '        End If

    '        'Copy the files specified by the "copyfiles" attribute from src to dest
    '        'src = "C:\...\...\<wsProjectName>\<file.ext>
    '        'dest =Path Defined in <WebServices>\<wsProjectName>\<file.ext>

    '        Dim srcDir As String = proj.Replace(orgprojname, "")

    '        If lstDeployWebSvcFiles.Count > 0 Then
    '            For i As Integer = 0 To lstDeployWebSvcFiles.Count - 1
    '                'Search for the filetype in the web service project's src directory
    '                Dim objfs As New FileSearch
    '                Dim filetype As String = "*." + CType(lstDeployWebSvcFiles(i), String)
    '                objfs.Search(New DirectoryInfo(srcDir), filetype)
    '                Dim totFiles As Integer = objfs.Files.Count

    '                For indx As Integer = 0 To totFiles - 1
    '                    Dim wsfile As FileInfo = CType(objfs.Files.Item(indx), FileInfo)
    '                    Dim srcWebSvcFile As String = wsfile.FullName
    '                    Dim destWebSvcFile As String = deployWebSvcProjLoc + wsfile.Name
    '                    Try
    '                        If File.Exists(destWebSvcFile) Then
    '                            File.SetAttributes(destWebSvcFile, FileAttributes.Normal)
    '                        End If
    '                        File.Copy(srcWebSvcFile, destWebSvcFile, True)
    '                        If dispXMLoutput Then
    '                            Output("<message loc=""builddeploy""><![CDATA[" + " Deployed Web Service File: " + srcWebSvcFile + " ==> " + destWebSvcFile + "]]></message>")
    '                        End If
    '                    Catch ex As Exception
    '                        If dispXMLoutput Then
    '                            Output("<message loc=""builddeploy""><![CDATA[" + " Failed to Deployed Web Service File: " + srcWebSvcFile + " ==> " + destWebSvcFile + "]]></message>")
    '                        Else
    '                            Output(" Failed to Deployed Web Service File: " + srcWebSvcFile + " ==> " + destWebSvcFile, ConsoleTools.ConsoleColor.red)
    '                        End If
    '                    End Try
    '                Next

    '            Next
    '        End If

    '    End If
    '    '-------------------------

    '    '--------------------------
    '    'If the project output type is standard library i.e. dll, then set up various deployment options
    '    If htOutputType.Contains(proj) Then
    '        If CType(htOutputType(proj), String).ToUpper.Equals("DLL") Then

    '            'Set up deployment of dll to the common build reference area specified by <BuildRefPath> tag
    '            dest = buildFileLocation + CType(BuildListMapProjToAssmbName(proj), String)
    '            If Not deployDllTo.Contains(dest) Then
    '                deployDllTo.Add(dest)
    '            End If

    '            'Set up deployment of dll to the  tagged location of the individual projects - 
    '            'NOTE: This is useful when you list out all the projects in the .xml file and want different
    '            'project assembly to be copied to specific locations
    '            If htCopyAssmbTo.Contains(proj) Then
    '                dest = CType(htCopyAssmbTo(proj), String) + CType(BuildListMapProjToAssmbName(proj), String)
    '                If Not deployDllTo.Contains(dest) Then
    '                    deployDllTo.Add(dest)
    '                End If
    '            End If

    '            'Set up deployment of  assembly to the location specificed by the <Libraries> tag
    '            If htCopyTo.Contains(CType(htOutputType(proj), String)) Then
    '                dest = htCopyTo(CType(htOutputType(proj), String)) + CType(BuildListMapProjToAssmbName(proj), String)
    '                If Not deployDllTo.Contains(dest) Then
    '                    deployDllTo.Add(dest)
    '                End If
    '            End If

    '        End If
    '    End If
    '    '-----------------------

    '    '----------------------
    '    'Now deploy the assembly to all the various destination listed in "deployDllTo" 
    '    Dim en As IEnumerator
    '    src = CType(BuildListMapProjToAssmbLoc(proj), String)
    '    en = deployDllTo.GetEnumerator
    '    While en.MoveNext
    '        Try
    '            File.Copy(src, CType(en.Current, String), True)
    '            If dispXMLoutput Then
    '                Output("<message loc=""builddeploy""><![CDATA[" + "Deployed " + src + "  ==> " + CType(en.Current, String) + "]]></message>")
    '            End If
    '        Catch ex As Exception
    '            If dispXMLoutput Then
    '                Output("<message loc=""builddeploy""><![CDATA[" + "Failed to deploy " + src + "  ==> " + CType(en.Current, String) + "]]></message>")
    '                Output("<message loc=""builddeploy""><![CDATA[" + ex.Message + "]]></message>")
    '            Else
    '                Output("Failed to deploy DLL  to : " + CType(en.Current, String) + " ! " + vbCrLf + ex.Message, ConsoleTools.ConsoleColor.red)
    '            End If
    '            buildSuccess = False
    '        End Try
    '    End While
    '    '----------------------

    '    '---------------------------------
    '    'If poroject's otuput type is EXE, then copy the whole output directory to the specifiec location as per the <Deploy/Applications> in configuration settings
    '    If htOutputType.Contains(proj) Then
    '        If CType(htOutputType(proj), String).ToUpper.Equals("EXE") Then

    '            'Copy the default output directory '\bin' to the location specified in the <Applications id="exe">...</Applications> tag
    '            deployExeProjName = CType(ProjectsToAssmb(proj), String).Replace(".exe", "")
    '            Dim srcOutputDir As String = proj.Replace(orgprojname, CType(htOutputPath(CType(ProjectsToAssmb(proj), String)), String).Replace("\", ""))
    '            Dim deployExeProjLoc As String = AddBackSlashAtTheEnd(CType(htCopyTo("exe"), String)) + deployExeProjName
    '            CleanOutputDir(deployExeProjLoc)
    '            CopyDirectory(srcOutputDir, deployExeProjLoc)
    '            If dispXMLoutput Then
    '                Output("<message loc=""builddeploy""><![CDATA[ Deployed " + srcOutputDir + " ==> " + deployExeProjLoc + "]]></message>")
    '            End If

    '            'Copy the folders specified by the "copydirs" attribute of the <Applications id="exe" copydir="">...</Applications> from src to dest
    '            If lstDeployAppDir.Count > 0 Then
    '                For i As Integer = 0 To lstDeployAppDir.Count - 1
    '                    srcOutputDir = proj.Replace(orgprojname, CType(lstDeployAppDir(i), String))
    '                    CopyDirectory(srcOutputDir, deployExeProjLoc)
    '                    If dispXMLoutput Then
    '                        Output("<message loc=""builddeploy""><![CDATA[" + "Deployed " + srcOutputDir + " ==> " + deployExeProjLoc + "]]></message>")
    '                    End If
    '                Next
    '            End If

    '            If htCopyAssmbTo.Contains(proj) Then
    '                srcOutputDir = proj.Replace(orgprojname, CType(htOutputPath(CType(ProjectsToAssmb(proj), String)), String).Replace("\", ""))
    '                deployExeProjLoc = AddBackSlashAtTheEnd(CType(htCopyAssmbTo(proj), String)) + deployExeProjName
    '                CleanOutputDir(deployExeProjLoc)
    '                CopyDirectory(srcOutputDir, deployExeProjLoc)
    '                If dispXMLoutput Then
    '                    Output("<message loc=""builddeploy""><![CDATA[ Deployed " + srcOutputDir + " ==> " + deployExeProjLoc + "]]></message>")
    '                End If
    '            End If

    '        End If
    '    End If
    '    '-----------------------

    '    Return buildSuccess

    'End Function

    Private Function DoDeployment(ByVal proj As String) As Boolean
        Dim deploySuccess As Boolean = True
        Dim src As String
        Dim dest As String
        Dim srcOutputDir As String
        Dim deployProjLoc As String = String.Empty
        Dim deployProjName As String = String.Empty
        Dim orgprojname As String

        Dim tmparr() As String = proj.Split("\"c)
        orgprojname = tmparr(tmparr.Length - 1)
        If InStr(orgprojname, ".vbproj") Then
            deployProjName = orgprojname.Replace(".vbproj", "")
        End If
        If InStr(orgprojname, ".csproj") Then
            deployProjName = orgprojname.Replace(".csproj", "")
        End If

        If htOutputType.Contains(proj) Then


            If CType(htOutputType(proj), String).ToUpper.Equals("DLL") Then

                deployProjName = CType(ProjectsToAssmb(proj), String).Replace(".dll", "")


                'Get the source .DLL library
                src = CType(BuildListMapProjToAssmbLoc(proj), String)

                'Deploy library (DLL) assembly to <BuildRefPath> location
                dest = buildFileLocation + CType(BuildListMapProjToAssmbName(proj), String)
                File.Copy(src, dest, True)

                'Deploy library to location specificed by the <Libraries> tag
                If htCopyTo.Contains(CType(htOutputType(proj), String)) Then
                    dest = htCopyTo(CType(htOutputType(proj), String)) + CType(BuildListMapProjToAssmbName(proj), String)
                    File.Copy(src, dest, True)
                End If

                If htCopyFiles.Count > 0 Then
                    Dim en As IDictionaryEnumerator = htCopyFiles.GetEnumerator
                    While en.MoveNext
                        If String.Compare(en.Key, "DLL", True) = 0 Then
                            Dim filelist As ArrayList = DirectCast(en.Value, ArrayList)
                            For i As Integer = 0 To filelist.Count - 1
                                Dim objfs As New FileSearch
                                Dim filetype As String = "*." + CType(filelist(i), String)
                                objfs.Search(New DirectoryInfo(proj.Replace(orgprojname, "")), filetype)
                                Dim totFiles As Integer = objfs.Files.Count
                                For indx As Integer = 0 To totFiles - 1
                                    Dim finfo As FileInfo = CType(objfs.Files.Item(indx), FileInfo)
                                    Dim srcFile As String = finfo.FullName
                                    Dim destfile As String = AddBackSlashAtTheEnd(htCopyTo(CType(htOutputType(proj), String))) + finfo.Name
                                    File.Copy(srcFile, destfile, True)
                                Next
                            Next
                        End If
                    End While
                End If


                '-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                '[START] - Deploy Web Service
                'if the project is a web service (output type will always be a DLL) and there is a 
                '<WebServices id="websvc"></WebService> tag in the config file, then setup deployment accordingly
                '-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                If htOutputType.Contains(proj) And WebSvcProjects.Contains(proj) And htCopyTo.Contains("websvc") Then

                    If ProjectDirectoryInfo.Contains(proj) Then
                        Dim projdirinfo As DirectoryInfo = DirectCast(ProjectDirectoryInfo(proj), DirectoryInfo)
                        If projdirinfo.Parent.Name.ToLower.Equals("web services") Then
                            deployProjName = projdirinfo.Name()
                        End If
                    End If

                    Dim deployWebSvcProjLoc As String = AddBackSlashAtTheEnd(AddBackSlashAtTheEnd(CType(htCopyTo("websvc"), String)) + deployProjName)

                    CleanOutputDir(deployWebSvcProjLoc)

                    'Copy the folders specified by the "copydirs" attribute from src to dest
                    If lstDeployWebSvcDir.Count > 0 Then
                        For i As Integer = 0 To lstDeployWebSvcDir.Count - 1
                            srcOutputDir = proj.Replace(orgprojname, CType(lstDeployWebSvcDir(i), String))
                            CopyDirectory(srcOutputDir, deployWebSvcProjLoc)
                            If dispXMLoutput Then
                                Output("<message loc=""builddeploy""><![CDATA[" + "Deployed Web Service Dir:" + srcOutputDir + " ==> " + deployWebSvcProjLoc + "]]></message>")
                            End If
                        Next
                    End If

                    'Copy the files specified by the "copyfiles" attribute from src to dest

                    'NOTE:    src = "C:\...\...\<wsProjectName>\<file.ext>
                    '               dest =Path Defined in <WebServices>\<wsProjectName>\<file.ext>

                    Dim srcDir As String = proj.Replace(orgprojname, "")

                    If lstDeployWebSvcFiles.Count > 0 Then
                        For i As Integer = 0 To lstDeployWebSvcFiles.Count - 1
                            'Search for the filetype in the web service project's src directory
                            Dim objfs As New FileSearch
                            Dim filetype As String = "*." + CType(lstDeployWebSvcFiles(i), String)
                            objfs.Search(New DirectoryInfo(srcDir), filetype)
                            Dim totFiles As Integer = objfs.Files.Count
                            For indx As Integer = 0 To totFiles - 1
                                Dim wsfile As FileInfo = CType(objfs.Files.Item(indx), FileInfo)
                                Dim srcWebSvcFile As String = wsfile.FullName
                                Dim destWebSvcFile As String = deployWebSvcProjLoc + wsfile.Name
                                Try
                                    If File.Exists(destWebSvcFile) Then
                                        File.SetAttributes(destWebSvcFile, FileAttributes.Normal)
                                    End If
                                    File.Copy(srcWebSvcFile, destWebSvcFile, True)
                                    If dispXMLoutput Then
                                        Output("<message loc=""builddeploy""><![CDATA[" + " Deployed Web Service File: " + srcWebSvcFile + " ==> " + destWebSvcFile + "]]></message>")
                                    End If
                                Catch ex As Exception
                                    If dispXMLoutput Then
                                        Output("<message loc=""builddeploy""><![CDATA[" + " Failed to Deployed Web Service File: " + srcWebSvcFile + " ==> " + destWebSvcFile + "]]></message>")
                                    Else
                                        Output(" Failed to Deployed Web Service File: " + srcWebSvcFile + " ==> " + destWebSvcFile, ConsoleTools.ConsoleColor.red)
                                    End If
                                End Try
                            Next
                        Next
                    End If

                End If

                '[END] - Deploy Web Service:
                '--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

            End If '//check if project is DLL


            If CType(htOutputType(proj), String).ToUpper.Equals("EXE") Then

                'Copy the default output directory i.e. '\bin' to the location (if specified) in the <Applications id="exe">...</Applications> tag
                If htCopyTo.Contains("exe") Then
                    deployProjName = CType(ProjectsToAssmb(proj), String).Replace(".exe", "")
                    srcOutputDir = proj.Replace(orgprojname, CType(htOutputPath(CType(ProjectsToAssmb(proj), String)), String).Replace("\", ""))
                    deployProjLoc = AddBackSlashAtTheEnd(CType(htCopyTo("exe"), String)) + deployProjName
                    CleanOutputDir(deployProjLoc)
                    CopyDirectory(srcOutputDir, deployProjLoc)
                End If

                'Copy the folders specified by the "copydirs" attribute of the <Applications id="exe" copydir="">...</Applications> from src to dest
                If lstDeployAppDir.Count > 0 Then
                    For i As Integer = 0 To lstDeployAppDir.Count - 1
                        srcOutputDir = proj.Replace(orgprojname, CType(lstDeployAppDir(i), String))
                        CopyDirectory(srcOutputDir, deployProjLoc)
                    Next
                End If

                'Check if projects to build are tagged 
                If htDeployProjectsToBuild.Contains(proj) Then
                    Dim deployToTag As String = CType(htDeployProjectsToBuild(proj), String)
                    'Check if there is a tag "copydir" - If yes, then deploy those specific directories
                    If htCopyDirs.Contains(deployToTag) Then
                        Dim dirlist As ArrayList = CType(htCopyDirs(deployToTag), ArrayList)
                        If dirlist.Count > 0 Then
                            'Copy the  source directories specified by "copydirs" tag
                            deployProjLoc = AddBackSlashAtTheEnd(CType(htCopyAssmbTo(proj), String)) + deployProjName
                            CleanOutputDir(deployProjLoc)
                            For i As Integer = 0 To dirlist.Count - 1
                                srcOutputDir = proj.Replace(orgprojname, CType(dirlist(i), String))
                                CopyDirectory(srcOutputDir, deployProjLoc)
                            Next
                        End If '// check if dirlist.Count > 0
                    Else
                        'Copy the complete source parent directory structure (including all sub-dirs and files) of this EXE
                        srcOutputDir = proj.Replace(String.Concat("\", orgprojname), "")
                        deployProjLoc = AddBackSlashAtTheEnd(CType(htCopyAssmbTo(proj), String))
                        CleanOutputDir(deployProjLoc + deployProjName)
                        CopyDirectory(srcOutputDir, deployProjLoc)
                    End If '//check if htCopyDirs.Contains(deployToTag)
                End If '//htDeployProjectsToBuild.Contains(proj) 

            End If '// check if project is EXE

        End If '//check if htOutputType.Contains(proj) 

        Return deploySuccess

    End Function

    Private Function DoCustomDeployment() As Boolean

    End Function

#End Region

#Region "Helper Functions"

    Private Function GetDotNetVersion(ByVal projectname As String) As DOTNETVERSION

        Dim dotnetver As DOTNETVERSION
        Dim reader As XmlTextReader = New XmlTextReader(projectname)
        reader.Read()
        Dim firstElementName As String = reader.Name
        If firstElementName.Equals("VisualStudioProject") Then
            dotnetver = DOTNETVERSION.ONE
        Else
            dotnetver = DOTNETVERSION.TWO
        End If
        reader.Close()
        reader = Nothing

        Return dotnetver

    End Function

    Private Function GetUserName(ByVal ticid As String) As String

        Dim username As String = String.Empty

        If String.Compare(ticid, String.Empty) <> 0 Then
            'First try against PROD domain
            username = GetUserInfoFromLDAP(ticid, "PROD", "displayname")
            If String.Compare(username, String.Empty) = 0 Then
                'Try against APPDMZ
                username = GetUserInfoFromLDAP(ticid, "APPDMZ", "displayname")
                If String.Compare(username, String.Empty) = 0 Then
                    username = ticid
                End If
            End If
        End If


        Return username

    End Function

    Private Function GetUserInfoFromLDAP(ByVal ticid As String, ByVal domain As String, ByVal propname As String) As String
        Dim propvalue As String = String.Empty

        Try

            Dim rootEntry As New DirectoryEntry("LDAP://" + domain)
            Dim searcher As New DirectorySearcher(rootEntry)
            Dim filter As String = String.Empty
            Dim results As SearchResultCollection

            If String.Compare(ticid, String.Empty) <> 0 Then
                filter = "(cn= " & ticid & ")"
            End If

            searcher.Filter = filter
            results = searcher.FindAll()

            If results.Count > 0 Then
                Dim resultrow As SearchResult = Nothing
                Dim Key As String = String.Empty
                resultrow = results.Item(0)
                For Each Key In resultrow.Properties.PropertyNames
                    If String.Compare(propname, String.Empty) <> 0 Then
                        Select Case Key.ToUpper
                            Case propname.ToUpper
                                propvalue = resultrow.Properties(Key).Item(0).ToString
                                Exit For
                        End Select
                    End If
                Next
            End If

        Catch ex As Exception
            Output("Exception at GetUserInfoFromLDAP() - " + vbCrLf + ex.ToString, ConsoleTools.ConsoleColor.red)
        End Try

        Return propvalue

    End Function

    Private Function CreateTimeStamp(ByVal time As Date) As String
        Dim timestamp As String = time.Year.ToString + time.Month.ToString + time.Day.ToString + "-" + time.Hour.ToString + time.Minute.ToString + time.Second.ToString
        Return timestamp
    End Function

    Private Function ContainsKey(ByVal htbl As Hashtable, ByVal searchkey As String, ByRef actualkey As String) As Boolean

        Dim boolcontainskey As Boolean = False

        For Each key As Object In htbl.Keys
            If String.Compare(key.ToString, searchkey, True) = 0 Then
                boolcontainskey = True
                actualkey = key.ToString
                Exit For
            End If
        Next

        Return boolcontainskey

    End Function

    Private Function ContainsKey(ByVal sortlist As SortedList, ByVal searchkey As String) As Boolean

        Dim boolcontainskey As Boolean = False

        For Each key As Object In sortlist.Keys
            If String.Compare(key.ToString, searchkey, True) = 0 Then
                boolcontainskey = True
                Exit For
            End If
        Next

        Return boolcontainskey

    End Function

    Private Function ContainsKey(ByVal sortlist As SortedList, ByVal searchkey As String, ByRef actualkey As String) As Boolean

        Dim boolcontainskey As Boolean = False

        For Each key As Object In sortlist.Keys
            If String.Compare(key.ToString, searchkey, True) = 0 Then
                boolcontainskey = True
                actualkey = key.ToString
                Exit For
            End If
        Next

        Return boolcontainskey

    End Function

    Private Function AddBackSlashAtTheEnd(ByVal str As String) As String
        If Not str Is Nothing AndAlso String.Compare(str, String.Empty) <> 0 AndAlso Not str.EndsWith("\") Then
            str = str + "\"
        End If
        Return str
    End Function

    Private Function AddForwardSlashAtTheEnd(ByVal str As String) As String
        If Not str Is Nothing AndAlso String.Compare(str, String.Empty) <> 0 AndAlso Not str.EndsWith("/") Then
            str = str + "/"
        End If
        Return str
    End Function

    Private Sub UnhandledExceptionHandler(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
        'Release the lock
        ReleaseLock(buildlockfile)

        'Delete the entry from the queue
        If File.Exists(AddBackSlashAtTheEnd(locksdir) + currentProcessId + ".txt") Then
            File.Delete(AddBackSlashAtTheEnd(locksdir) + currentProcessId + ".txt")
        End If
    End Sub

    Private Function CannotProceed(ByVal pid As String) As Boolean
        Dim blCannotProceed As Boolean

        Dim pFile As String = AddBackSlashAtTheEnd(locksdir) + pid + ".txt"

        If Not File.Exists(pFile) Then
            Dim fs As FileStream = File.Create(pFile)
            fs.Close()
        End If

        Dim allfiles() As FileInfo = lockdirinfo.GetFiles("*.txt")
        Array.Sort(allfiles, New CompareFileInfo)
        Array.Reverse(allfiles)

        If String.Compare(allfiles(0).Name, pid + ".txt") = 0 Then
            blCannotProceed = False
        Else
            blCannotProceed = True
        End If

        Return blCannotProceed
    End Function

    Private Function GetLockFileName(ByVal projfile As String) As String
        Dim lockFile As String = String.Empty
        Dim tmparr() As String = projfile.Split("\"c)
        Dim projname As String = tmparr(tmparr.Length - 1)
        If InStr(projname, ".vbproj") Then
            lockFile = projname.Replace(".vbproj", ".lock")
        End If
        If InStr(projname, ".csproj") Then
            lockFile = projname.Replace(".csproj", ".lock")
        End If
        Return AddBackSlashAtTheEnd(locksdir) + lockFile
    End Function

    Private Sub CreateLock(ByVal lockfile As String)
        Dim fs As FileStream = File.Create(lockfile)
        fs.Close()
    End Sub

    Private Sub ReleaseLock(ByVal lockfile As String)
        If File.Exists(lockfile) Then
            File.SetAttributes(lockfile, FileAttributes.Normal)
            File.Delete(lockfile)
        End If
    End Sub

    Private Function IsLocked(ByVal lockfile As String) As Boolean
        Dim locked As Boolean

        If File.Exists(lockfile) Then
            locked = True
        Else
            locked = False
        End If

        Return locked
    End Function

    Private Sub CopyDirectory(ByVal srcDir As String, ByVal destDir As String)

        If Directory.Exists(srcDir) Then

            destDir = AddBackSlashAtTheEnd(destDir) + New DirectoryInfo(srcDir).Name

            If Not Directory.Exists(destDir) Then
                Directory.CreateDirectory(destDir)
            End If

            Dim entries() As String = Directory.GetFileSystemEntries(srcDir)
            For Each entry As String In entries
                If Directory.Exists(entry) Then
                    CopyDirectory(entry, destDir)
                End If
                If File.Exists(entry) Then
                    Dim destFile As String = AddBackSlashAtTheEnd(destDir) + New FileInfo(entry).Name
                    If File.Exists(destFile) Then
                        File.SetAttributes(destFile, FileAttributes.Normal)
                    End If
                    Try
                        File.Copy(entry, destFile, True)
                    Catch ex As Exception
                        If dispXMLoutput Then
                            Output("<message loc=""copydirectory""><![CDATA[" + "Failed to copy " + entry + "  ==> " + destFile + "]]></message>")
                            Output("<message loc=""copydirectory""><![CDATA[" + ex.Message + "]]></message>")
                        Else
                            Output("Failed to copy " + entry + "  ==> " + destFile + " ! " + vbCrLf + ex.Message, ConsoleTools.ConsoleColor.red)
                        End If
                    End Try
                End If
            Next

        End If

    End Sub

    Private Sub CleanOutputDir(ByVal outputDir As String)
        If Directory.Exists(outputDir) Then
            Dim entries() As String = Directory.GetFileSystemEntries(outputDir)
            For Each entry As String In entries
                If Directory.Exists(entry) Then
                    CleanOutputDir(entry)
                End If
                If File.Exists(entry) Then
                    File.SetAttributes(entry, FileAttributes.Normal)
                    Try
                        File.Delete(entry)
                    Catch ex As Exception
                        If blParallelBuild Then
                            ParallelBuildLog.Add("Unable to delete file : " + entry + " in " + outputDir)
                        Else
                            WriteLog("Unable to delete file : " + entry + " in " + outputDir)
                        End If
                    End Try

                End If
            Next
            Try
                Directory.Delete(outputDir)
            Catch ex As Exception
                WriteLog("Unable to delete directory : " + outputDir)
            End Try
        End If
    End Sub

    Private Sub MoveMSBuildErrorLogs(ByVal srcfile As String, ByVal destfile As String)
        'Move the error log file to the error directory
        If File.Exists(destfile) Then
            File.Delete(destfile)
        End If
        File.Move(srcfile, destfile)

        If blCreateASingleMSBuildErrorLogFile Then
            'Append to the single error log file

            'Load the single error log file
            If File.Exists(UBuildSingleMsbuildErrorLogFile) AndAlso File.Exists(destfile) Then

                Try
                    Dim xmldoc As XmlDocument = New XmlDocument
                    xmldoc.Load(UBuildSingleMsbuildErrorLogFile)

                    Dim msbuildNode As XmlNode = xmldoc.GetElementsByTagName("MSBuilds")(0)

                    'Load the error log file
                    Dim xmldocerr As XmlDocument = New XmlDocument
                    xmldocerr.Load(destfile)

                    Dim msbuilderrNode As XmlNode = xmldocerr.GetElementsByTagName("msbuild")(0)

                    If Not msbuildNode Is Nothing AndAlso Not msbuilderrNode Is Nothing Then
                        'Append to the single error log file information from the specific error log file
                        msbuildNode.AppendChild(xmldoc.ImportNode(msbuilderrNode, True))

                        'Save
                        xmldoc.Save(UBuildSingleMsbuildErrorLogFile)
                    End If

                    xmldoc = Nothing
                    xmldocerr = Nothing
                Catch ex As Exception
                    WriteLog("Exception at MoveMSBuildErrorLogs() - Failed to create single log file " + vbCrLf + +ex.ToString)
                End Try


            End If

        End If
    End Sub

    Private Sub UpdateProjUserSettings(ByVal projuser As String, ByVal refpath As String)

        Dim xmldoc As XmlDocument = New XmlDocument
        Dim xnl As XmlNodeList
        Dim xelement As XmlElement = Nothing
        Dim oldrefpath As String = String.Empty
        Dim doSave As Boolean = False

        File.SetAttributes(projuser, FileAttributes.Normal)

        xmldoc.Load(projuser)

        '.Net 1.1
        xnl = xmldoc.SelectNodes("//Settings")

        If xnl.Count = 1 Then
            For Each xelement In xnl
                If xelement.HasAttribute("ReferencePath") Then
                    oldrefpath = xelement.Attributes.GetNamedItem("ReferencePath").Value
                End If
            Next
            If Not xelement Is Nothing AndAlso Not oldrefpath Is Nothing Then
                xelement.SetAttribute("ReferencePath", refpath)
                doSave = True
            End If
        Else
            '.Net 2.0
            xnl = xmldoc.GetElementsByTagName("ReferencePath")
            If xnl.Count = 1 Then
                xelement = xnl.Item(0)
                If Not xelement Is Nothing Then
                    xelement.InnerText = refpath
                    doSave = True
                End If
            End If
        End If

        If doSave Then
            xmldoc.Save(projuser)
        End If

        File.SetAttributes(projuser, FileAttributes.ReadOnly)

        xmldoc = Nothing

    End Sub

    Private Function UpdateHintPath(ByVal projfile As String) As Boolean

        Dim xmldoc As XmlDocument
        Dim xnl As XmlNodeList
        Dim xelement As XmlElement
        Dim hintpathAttr As String = String.Empty
        Dim newHintPathAttr As String
        Dim name As String = String.Empty
        Dim assmbname As String = String.Empty
        Dim refinclude As String
        Dim projGUID As String = String.Empty
        Dim blDoSave As Boolean = False
        Dim blUpdateHintPathOk As Boolean = True
        Dim elementToRemove As New Hashtable
        Dim attrToRemove As New ArrayList
        Dim ien As IEnumerator

        File.SetAttributes(projfile, FileAttributes.Normal)

        xmldoc = New XmlDocument
        xmldoc.Load(projfile)

        If GetDotNetVersion(projfile) = DOTNETVERSION.TWO Then

            'Get the namespace URI of the projects
            Dim projectroot As XmlNode = xmldoc.ChildNodes(0)
            If projectroot.Name.Equals("xml") Then
                projectroot = xmldoc.ChildNodes(1)
            End If
            Dim projectNameSpaceURI As String = CType(projectroot, System.Xml.XmlNode).NamespaceURI
            Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xmldoc.NameTable)
            nsmgr.AddNamespace("proj", projectNameSpaceURI)

            'Remove all project references  - We need to remove the project reference becuase as UBuild build at project level and not sln
            'if one of the referred project is not already build but is a dependent of the main project being built it will cause the build to fail
            'So we take out the project reference.

            xnl = xmldoc.GetElementsByTagName("ItemGroup")

            For Each xelement In xnl
                If xelement.HasChildNodes Then
                    Dim childNodeList As XmlNodeList = xelement.ChildNodes
                    For Each _child As XmlNode In childNodeList
                        If _child.NodeType = XmlNodeType.Comment Then
                            Continue For
                        End If
                        Dim child As XmlElement = DirectCast(_child, XmlElement)
                        If child.Name.Equals("ProjectReference") Then

                            If Not elementToRemove.Contains(child) Then
                                elementToRemove.Add(child, xelement)
                            End If

                            If child.HasChildNodes Then
                                If child.GetElementsByTagName("Project").Count = 1 Then
                                    projGUID = child.GetElementsByTagName("Project").Item(0).InnerText
                                End If
                                If child.GetElementsByTagName("Name").Count = 1 Then
                                    assmbname = child.GetElementsByTagName("Name").Item(0).InnerText
                                End If
                            End If

                            'assmbname = child.ChildNodes(0).InnerText
                            'projGUID = child.ChildNodes(1).InnerText

                            Dim newelement As XmlElement = xmldoc.CreateElement("Reference", projectNameSpaceURI)
                            Dim xmlName As XmlElement = xmldoc.CreateElement("Name", projectNameSpaceURI)
                            Dim xmlHintPath As XmlElement = xmldoc.CreateElement("HintPath", projectNameSpaceURI)

                            xmlName.InnerText = CType(htProjGuidAssmb(projGUID), String)
                            xmlHintPath.InnerText = buildFileLocation & CType(htProjGuidAssmb(projGUID), String) & ".dll"
                            newelement.SetAttribute("Include", CType(htProjGuidAssmb(projGUID), String))

                            newelement.AppendChild(xmlName)
                            newelement.AppendChild(xmlHintPath)

                            xelement.AppendChild(newelement)

                            xmldoc.Save(projfile)

                            If Not attrToRemove.Contains(newelement) Then
                                attrToRemove.Add(newelement)
                            End If

                        End If '//If child.Name.Equals("ProjectReference")

                        'Find <Reference> element is present without any child node
                        'Remove if it is of type <Reference Include="[AssemblyName], Version=1.0.915.2008, Culture=neutral, processorArchitecture=MSIL" />
                        If child.Name.Equals("Reference") And child.HasAttribute("Include") And Not child.HasChildNodes Then

                            refinclude = child.GetAttribute("Include")

                            If InStr(refinclude, ",") Then

                                assmbname = child.GetAttribute("Include").Split(","c)(0)

                                If Not ToBeExcluded(assmbname) Then

                                    If Not elementToRemove.Contains(child) Then
                                        elementToRemove.Add(child, xelement)
                                    End If

                                    Dim newelement As XmlElement = xmldoc.CreateElement("Reference", projectNameSpaceURI)
                                    Dim xmlName As XmlElement = xmldoc.CreateElement("Name", projectNameSpaceURI)
                                    Dim xmlHintPath As XmlElement = xmldoc.CreateElement("HintPath", projectNameSpaceURI)

                                    xmlName.InnerText = assmbname
                                    xmlHintPath.InnerText = assmbname & ".dll"
                                    newelement.SetAttribute("Include", assmbname)

                                    newelement.AppendChild(xmlName)
                                    newelement.AppendChild(xmlHintPath)

                                    xelement.AppendChild(newelement)

                                    xmldoc.Save(projfile)

                                    If Not attrToRemove.Contains(newelement) Then
                                        attrToRemove.Add(newelement)
                                    End If
                                End If

                            Else
                                refinclude = String.Empty
                            End If '// If InStr(refinclude, ",")

                        End If '//If child.Name.Equals("Reference")

                    Next
                End If
            Next

            'If there are project references found, then lets remove them now
            If elementToRemove.Count > 0 Then
                ien = elementToRemove.Keys.GetEnumerator
                While ien.MoveNext
                    Dim _childElement As XmlElement = CType(ien.Current, XmlElement)
                    Dim _parentElement As XmlElement = (CType(elementToRemove(ien.Current), XmlElement))
                    _parentElement.RemoveChild(_childElement)
                End While
                xmldoc.Save(projfile)
            End If

            'Now update all the hint paths
            xnl = xmldoc.GetElementsByTagName("Reference")

            For Each xelement In xnl
                refinclude = ""
                assmbname = ""
                If xelement.HasChildNodes Then

                    If xelement.HasAttribute("Include") Then
                        refinclude = xelement.GetAttribute("Include")
                        If InStr(refinclude, ",") Then
                            assmbname = refinclude.Split(","c)(0)
                        ElseIf ProjectsToBuildList.Contains(refinclude & ".dll") Then
                            assmbname = refinclude
                        ElseIf IsProxy(refinclude & ".dll") Then
                            assmbname = refinclude
                        End If
                    End If

                    'check if there is a <HintPath> element present
                    Dim hintpathnode As XmlNode = Nothing
                    For i As Integer = 0 To xelement.ChildNodes.Count - 1
                        If String.Compare(xelement.ChildNodes(i).Name, "HintPath") = 0 Then
                            hintpathnode = xelement.ChildNodes(i)
                            Exit For
                        End If
                    Next
                    If ((hintpathnode Is Nothing) And Not ToBeExcluded(assmbname) And assmbname.Length > 0) Then
                        'TODO: Add an <HintPath> element
                        hintpathnode = xmldoc.CreateElement("HintPath", "http://schemas.microsoft.com/developer/msbuild/2003")
                        hintpathnode.InnerText = assmbname
                        xelement.AppendChild(hintpathnode)
                    End If

                    Dim childNodeList As XmlNodeList = xelement.ChildNodes

                    For Each child As XmlElement In childNodeList

                        If child.Name.Equals("Name") Then
                            assmbname = child.InnerText
                        End If
                        If child.Name.Equals("HintPath") Then
                            hintpathAttr = child.InnerText
                        End If

                        If Not assmbname Is Nothing And assmbname.Length > 0 And ToBeExcluded(assmbname) And IsProxy(assmbname & ".dll") Then
                            newHintPathAttr = buildFileLocation & assmbname & ".dll"
                            If proxiesList.Contains(assmbname) And Not File.Exists(newHintPathAttr) Then
                                File.Copy(CType(proxiesList(assmbname), String), newHintPathAttr, True)
                            End If
                            If child.Name.Equals("HintPath") Then
                                child.InnerText = buildFileLocation & assmbname & ".dll"
                            End If
                            blDoSave = True
                        End If

                        If child.Name.Equals("HintPath") And Not assmbname Is Nothing And assmbname.Length > 0 And Not ToBeExcluded(assmbname) And Not hintpathAttr Is Nothing AndAlso hintpathAttr.Length > 0 Then
                            newHintPathAttr = buildFileLocation & assmbname & ".dll"
                            If Not ProjectsToBuildList.Contains(assmbname & ".dll") And Not File.Exists(newHintPathAttr) And IsProxy(assmbname & ".dll") Then
                                If proxiesList.Contains(assmbname & ".dll") Then
                                    File.Copy(CType(proxiesList(assmbname & ".dll"), String), newHintPathAttr, True)
                                End If
                            End If
                            child.InnerText = buildFileLocation & assmbname & ".dll"
                            blDoSave = True
                        End If
                    Next '// child In childNodeList

                End If '//if element has childnodes

            Next '//next <Reference> element

        Else 'DOTNET_VER = 1.0
            xnl = xmldoc.SelectNodes("//References/Reference")

            For Each xelement In xnl

                If xelement.HasAttribute("Name") Then
                    name = xelement.Attributes.GetNamedItem("Name").Value
                End If

                'If proxyAliasList.Contains(name) Then
                '    If xelement.HasAttribute("Guid") And _
                '    xelement.HasAttribute("VersionMajor") And _
                '    xelement.HasAttribute("VersionMinor") And _
                '    xelement.HasAttribute("Lcid") And _
                '    xelement.HasAttribute("WrapperTool") Then

                '        xelement.RemoveAttribute("Guid")
                '        xelement.RemoveAttribute("VersionMajor")
                '        xelement.RemoveAttribute("VersionMinor")
                '        xelement.RemoveAttribute("Lcid")
                '        xelement.RemoveAttribute("WrapperTool")

                '        xelement.SetAttribute("AssemblyName", CType(proxyAliasList(name), String))
                '        xelement.SetAttribute("HintPath", buildFileLocation & CType(proxyAliasList(name), String) + ".dll")

                '        blDoSave = True
                '    End If
                'End If

                'Remove project references
                If xelement.HasAttribute("Project") Then
                    xelement.RemoveAttribute("Project")
                    xelement.RemoveAttribute("Package")
                    If BuildListMapProjToAssmbName.Contains(projfile) Then
                        xelement.SetAttribute("AssemblyName", name)
                        xelement.SetAttribute("HintPath", buildFileLocation & name & ".dll")
                        blDoSave = True
                    End If
                End If

                If xelement.HasAttribute("AssemblyName") Then
                    assmbname = xelement.Attributes.GetNamedItem("AssemblyName").Value
                End If

                If xelement.HasAttribute("HintPath") Then
                    hintpathAttr = xelement.Attributes.GetNamedItem("HintPath").Value
                End If

                If ToBeExcluded(assmbname) And IsProxy(assmbname & ".dll") Then
                    newHintPathAttr = buildFileLocation & assmbname & ".dll"
                    If proxiesList.Contains(assmbname & ".dll") And Not File.Exists(newHintPathAttr) Then
                        File.Copy(CType(proxiesList(assmbname & ".dll"), String), newHintPathAttr, True)
                    End If
                    xelement.SetAttribute("HintPath", buildFileLocation & assmbname & ".dll")
                    blDoSave = True
                End If

                If Not assmbname Is Nothing And Not ToBeExcluded(assmbname) And Not hintpathAttr Is Nothing AndAlso hintpathAttr.Length > 0 Then
                    newHintPathAttr = buildFileLocation & assmbname & ".dll"
                    If Not ProjectsToBuildList.Contains(assmbname & ".dll") And Not File.Exists(newHintPathAttr) And IsProxy(assmbname & ".dll") Then
                        If proxiesList.Contains(assmbname & ".dll") Then
                            File.Copy(CType(proxiesList(assmbname & ".dll"), String), newHintPathAttr, True)
                        End If
                    End If
                    xelement.SetAttribute("HintPath", buildFileLocation & assmbname & ".dll")
                    blDoSave = True

                End If
            Next
        End If '//check DOTNET_VER

        Try
            If blDoSave Then
                xmldoc.Save(projfile)
            End If
        Catch ex As Exception
            If dispXMLoutput Then
                Output("<message loc=""updatehintpath""><![CDATA[ERROR while updating HintPath ! Failed to save : " + projfile + "]]> </message>")
                Output("<message loc=""updatehintpath""><![CDATA[" + ex.Message + "]]> </message>")
            Else
                Output(vbCrLf + "Error while updating HintPath ! Failed to save : " + projfile + vbCrLf + ex.Message, ConsoleTools.ConsoleColor.red)
            End If
            WriteLog(vbCrLf + "Error while updating HintPath ! Failed to save : " + projfile + vbCrLf + ex.Message)
            blUpdateHintPathOk = False
            Throw ex
        Finally
            xmldoc = Nothing
        End Try

        File.SetAttributes(projfile, FileAttributes.ReadOnly)

        Return blUpdateHintPathOk
    End Function

    Private Sub ResetColorAndVisitedStatus()
        Dim en As IDictionaryEnumerator
        en = AssemblyList.GetEnumerator
        While en.MoveNext
            Dim assmbnode As AssemblyNode = DirectCast(AssemblyList.Item(CType(en.Key, String)), AssemblyNode)
            assmbnode.NodeColor = AssemblyNode.NodeColorEnum.WHITE
            assmbnode.Visited = False
        End While
    End Sub

    Private Function ToBeExcluded(ByVal assemblyname As String) As Boolean
        If assemblyname Is Nothing Then
            Return False
        End If
        If assemblyname.StartsWith("System.") Or assemblyname.Equals("System") Or _
            assemblyname.StartsWith("mscorlib") Or _
                (assemblyname.StartsWith("Microsoft.") And Not TobeExcludedException(assemblyname)) Or _
                    assemblyname.StartsWith("CrystalDecisions.") Or _
                        assemblyname.StartsWith("stdole") Then
            Return True
        Else
            Return False
        End If
    End Function

    Private Function TobeExcludedException(ByVal assemblyname As String) As Boolean
        If assemblyname Is Nothing Then
            Return False
        End If
        If assemblyname.StartsWith("Microsoft.ApplicationBlocks.ExceptionManagement") Or _
        assemblyname.StartsWith("Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces") Then
            Return True
        Else
            Return False
        End If
    End Function

    Private Sub GetProxies()
        Dim en As IEnumerator
        Dim proxyloc As String = ""

        en = proxiesLoc.GetEnumerator
        While en.MoveNext
            proxyloc = CType(en.Current, String)
            If Directory.Exists(proxyloc) Then
                Dim files() As String = Directory.GetFiles(proxyloc)
                For Each f As String In files
                    If f.EndsWith(".dll") Then
                        Dim filename As String = f.Substring(f.LastIndexOfAny("\", f.Length - 1) + 1)
                        Dim src As String = proxyloc + filename
                        Dim dest As String = buildFileLocation + filename
                        If File.Exists(dest) Then
                            File.SetAttributes(dest, FileAttributes.Normal)
                        End If
                        File.Copy(src, dest, True)
                        If Not proxiesList.Contains(filename) Then
                            proxiesList.Add(filename, proxyloc + filename)
                        End If
                    End If
                Next
            End If
        End While
    End Sub

    Private Function IsProxy(ByVal assmbFilename As String) As Boolean
        Dim blProxy As Boolean
        If proxiesList.Contains(assmbFilename) Then
            blProxy = True
        Else
            blProxy = False
        End If
        Return blProxy
    End Function

    Private Function IsAlreadyBuilt(ByVal assmbFileName As String) As Boolean
        Dim alreadyBuilt As Boolean = False
        Dim builtFiles As String() = Directory.GetFiles(buildFileLocation)
        For Each fi As String In builtFiles
            If String.Compare(New FileInfo(fi).Name, assmbFileName) = 0 Then
                alreadyBuilt = True
                Exit For
            End If
        Next
        Return alreadyBuilt
    End Function

    Private Sub Output(ByVal msg As String, Optional ByVal color As ConsoleTools.ConsoleColor = ConsoleTools.ConsoleColor.grey, Optional ByVal newline As Boolean = True)
        If blParallelBuild Then

            Dim objLock As Object = New Object
            SyncLock objLock
                ConsoleTools.SetConsoleColors(color)
                If newline Then
                    Console.WriteLine(msg)
                Else
                    Console.Write(msg)
                End If
                ConsoleTools.SetConsoleColors(ConsoleTools.ConsoleColor.grey)
            End SyncLock

        Else
            ConsoleTools.SetConsoleColors(color)
            If newline Then
                Console.WriteLine(msg)
            Else
                Console.Write(msg)
            End If
            ConsoleTools.SetConsoleColors(ConsoleTools.ConsoleColor.grey)
        End If


    End Sub

    Private Sub DisplayErrMsgInNotePad(ByVal msgfile As String)
        If File.Exists(msgfile) Then
            Process.Start("notepad.exe", msgfile)
        End If
    End Sub

    Private Sub TabSpace(Optional ByVal n As Integer = 1)
        For i As Integer = 1 To n
            Console.Write(vbTab)
        Next
    End Sub

    Private Function GetFileExtension(ByVal filename As String) As String
        Dim ext As String = String.Empty
        If File.Exists(filename) Then
            Dim finfo As FileInfo = New FileInfo(filename)
            ext = finfo.Extension
        End If
        Return ext
    End Function
#End Region

#Region "Utilities"

    Private Sub DisplayWebReferencesXML()

        Dim _xmldoc As XmlDocument = New XmlDocument

        Dim projinfologfile As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_PROJECTINFO_LOG_FILENAME_XML

        Dim count As Integer = SortedBuildList.Count

        _xmldoc.Load(projinfologfile)

        For i As Integer = 0 To count - 1

            Dim proj As String = CType(SortedBuildList(i), String)
            Dim asmbnode As AssemblyNode = GenerateWebReferenceList(proj)

            'Creaet/Retreive the <Project name=''> element
            Dim projectelement As XmlElement = _xmldoc.SelectSingleNode("//Project[@name='" & proj & "']")
            If projectelement Is Nothing Then
                projectelement = _xmldoc.CreateElement("Project")
                projectelement.SetAttribute("name", proj)
                _xmldoc.DocumentElement.AppendChild(projectelement)
            End If

            If Not asmbnode.WebReferences Is Nothing AndAlso asmbnode.WebReferences.Rows.Count > 0 Then

                'Create/Retreive the <WebReferences> element
                Dim _webreferencesElement As XmlElement = projectelement.SelectSingleNode("WebReferences")
                If _webreferencesElement Is Nothing Then
                    _webreferencesElement = _xmldoc.CreateElement("WebReferences")
                    projectelement.AppendChild(_webreferencesElement)
                End If

                Dim totalrows As Integer = asmbnode.WebReferences.Rows.Count
                Dim totalcols As Integer = asmbnode.WebReferences.Columns.Count

                Dim ulrbehaviorcol As DataColumn = asmbnode.WebReferences.Columns(WEBREFDATATBL_COLUMNNAME_BEHAVIOR)

                For rindex As Integer = 0 To totalrows - 1
                    Dim urlvalofcurrentrow As String = CType(asmbnode.WebReferences.Rows(rindex)(ulrbehaviorcol), String)
                    If String.Compare(urlvalofcurrentrow, webreferencebehavior.ToString, True) = 0 OrElse (webreferencebehavior = WEBREFBEHAVIOR.ALL) Then

                        'Create the <WebReference> element
                        Dim webrefElement As XmlElement = _xmldoc.CreateElement("WebReference")
                        projectelement.AppendChild(webrefElement)

                        For Each col As DataColumn In asmbnode.WebReferences.Columns

                            Dim rowcolvalue As String = CType(asmbnode.WebReferences.Rows(rindex)(col.ColumnName), String)
                            Dim colnameElement As XmlElement = Nothing

                            Select Case col.ColumnName
                                Case WEBREFDATATBL_COLUMNNAME_REFERENCE
                                    colnameElement = _xmldoc.CreateElement("ReferenceName")
                                Case WEBREFDATATBL_COLUMNNAME_URL
                                    colnameElement = _xmldoc.CreateElement("Url")
                                Case WEBREFDATATBL_COLUMNNAME_BEHAVIOR
                                    colnameElement = _xmldoc.CreateElement("Behavior")
                            End Select

                            If Not colnameElement Is Nothing Then
                                colnameElement.InnerText = rowcolvalue
                                webrefElement.AppendChild(colnameElement)
                            End If
                        Next

                    End If
                Next

            End If
        Next

        _xmldoc.Save(projinfologfile)

    End Sub

    Private Sub DisplayWebReferences()

        WriteLog("Detecting web references ...")

        If dispXMLoutput Then
            Output("<step name=""DisplayWebReferences"">Detecting web references</step>")
        Else
            Output("Detecting web references...")
        End If

        Dim webreflogfile As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_WEBREFERENCES_LOG_FILENAME

        Dim count As Integer = SortedBuildList.Count

        'Write the column header
        WriteLog(webreflogfile, WEBREFDATATBL_COLUMNNAME_REFERENCE + vbTab, False)
        WriteLog(webreflogfile, WEBREFDATATBL_COLUMNNAME_URL + vbTab, False)
        WriteLog(webreflogfile, WEBREFDATATBL_COLUMNNAME_BEHAVIOR + vbTab, False)
        WriteLog(webreflogfile, WEBREFDATATBL_COLUMNNAME_REFERREDBY + vbTab, False)
        WriteLog(webreflogfile, WEBREFDATATBL_COLUMNNAME_PROJECT, True)

        For i As Integer = 0 To count - 1
            Dim proj As String = CType(SortedBuildList(i), String)
            Dim asmbnode As AssemblyNode = GenerateWebReferenceList(proj)
            If Not asmbnode.WebReferences Is Nothing AndAlso asmbnode.WebReferences.Rows.Count > 0 Then
                Dim totalrows As Integer = asmbnode.WebReferences.Rows.Count
                Dim totalcols As Integer = asmbnode.WebReferences.Columns.Count

                Dim ulrbehaviorcol As DataColumn = asmbnode.WebReferences.Columns(WEBREFDATATBL_COLUMNNAME_BEHAVIOR)

                For rindex As Integer = 0 To totalrows - 1
                    Dim urlvalofcurrentrow As String = CType(asmbnode.WebReferences.Rows(rindex)(ulrbehaviorcol), String)
                    If String.Compare(urlvalofcurrentrow, webreferencebehavior.ToString, True) = 0 Then
                        For cindex As Integer = 0 To totalcols - 1
                            Dim rowcolvalue As String = CType(asmbnode.WebReferences.Rows(rindex)(cindex), String)
                            If cindex = totalcols - 1 Then
                                WriteLog(webreflogfile, rowcolvalue)
                            Else
                                WriteLog(webreflogfile, rowcolvalue + vbTab, False)
                            End If
                        Next
                    End If
                Next

            End If
        Next

    End Sub

    Private Function GenerateWebReferenceList(ByVal lookinproject As String) As AssemblyNode
        Dim assmbnode As AssemblyNode = Nothing
        If BuildListMapProjToAssmbName.Contains(lookinproject) Then
            assmbnode = GenerateWebReferenceList(CType(BuildListMapProjToAssmbName(lookinproject), String), lookinproject, Nothing)
        End If
        Return assmbnode
    End Function

    Private Function GenerateWebReferenceList(ByVal assemblyname As String, ByVal lookInProject As String, ByVal tblname As String) As AssemblyNode

        Dim reader As XmlTextReader
        Dim asmnode As AssemblyNode
        Dim includeUrl As String = String.Empty
        Dim webRefUrl As String = String.Empty
        Dim urlBehavior As String = String.Empty
        Dim refName As String = String.Empty
        Dim rootNameSpace As String = String.Empty
        Dim relPath As String = String.Empty


        If assemblyname Is Nothing Then
            If BuildListMapProjToAssmbName.Contains(lookInProject) Then
                assemblyname = CType(BuildListMapProjToAssmbName(lookInProject), String)
            End If
        End If

        asmnode = CType(AssemblyList.Item(assemblyname), AssemblyNode)
        'lookInProject = CType(Me.htAllProjects(Me.SelectedAssemblyFromTheSet), String)


        If tblname Is Nothing OrElse String.Compare(tblname, String.Empty) = 0 Then
            tblname = "TblWebReference"
        End If

        Dim dt As New DataTable(tblname)
        Dim dr As DataRow
        Dim col1 As New DataColumn("Reference")
        Dim col2 As New DataColumn("Url")
        Dim col3 As New DataColumn("Behavior")
        Dim col4 As New DataColumn("ReferredBy")
        Dim col5 As New DataColumn("Project")
        dt.Columns.Add(col1)
        dt.Columns.Add(col2)
        dt.Columns.Add(col3)
        dt.Columns.Add(col4)
        dt.Columns.Add(col5)

        If Not asmnode Is Nothing Then

            If asmnode.WebReferences Is Nothing And Not lookInProject Is Nothing And File.Exists(lookInProject) Then

                If (GetDotNetVersion(lookInProject) = DOTNETVERSION.ONE) Then

                    reader = New XmlTextReader(lookInProject)
                    reader.Read()

                    While reader.Read
                        If reader.Name.Equals("Settings") And rootNameSpace Is Nothing Then
                            rootNameSpace = reader.GetAttribute("RootNamespace")
                        End If
                        If reader.Name.Equals("Folder") Then
                            webRefUrl = reader.GetAttribute("WebReferenceUrl")
                            urlBehavior = reader.GetAttribute("UrlBehavior")
                            refName = reader.GetAttribute("RelPath")

                            If Not webRefUrl Is Nothing Then
                                Dim tmparrRefName As String() = refName.Split("\"c)
                                dr = dt.NewRow
                                dr.Item("Reference") = tmparrRefName(1)
                                dr.Item("Url") = webRefUrl
                                dr.Item("Behavior") = urlBehavior
                                dr.Item("ReferredBy") = assemblyname
                                dr.Item("Project") = lookInProject
                                dt.Rows.Add(dr)
                            End If

                        End If
                    End While

                Else
                    'DOTNET VERSION = 2.0

                    Dim xmldoc As XmlDocument = New XmlDocument
                    xmldoc.Load(lookInProject)

                    Dim webrefurlNodeList As XmlNodeList = xmldoc.GetElementsByTagName("WebReferenceUrl")
                    For Each webrefurlelement As XmlElement In webrefurlNodeList

                        refName = String.Empty
                        webRefUrl = String.Empty
                        includeUrl = String.Empty
                        urlBehavior = String.Empty

                        If webrefurlelement.HasChildNodes Then

                            If webrefurlelement.HasAttribute("Include") Then
                                includeUrl = webrefurlelement.Attributes("Include").Value
                            End If

                            For Each webrefurlchildnode As XmlElement In webrefurlelement.ChildNodes

                                Select Case webrefurlchildnode.Name
                                    Case "UrlBehavior"
                                        urlBehavior = webrefurlchildnode.InnerText
                                    Case "UpdateFromURL"
                                        webRefUrl = webrefurlchildnode.InnerText
                                    Case "CachedSettingsPropName"
                                        refName = webrefurlchildnode.InnerText
                                        If Not String.IsNullOrEmpty(refName) Then
                                            Dim tmparrRefName As String() = refName.Split("_"c)
                                            refName = tmparrRefName(tmparrRefName.Length - 2)
                                        End If
                                    Case "RelPath"
                                        relPath = webrefurlchildnode.InnerText
                                End Select

                            Next

                            'If '<CachedSettingsPropName> is not available, get the reference name from <RelPath>
                            'Note: We can also get the 'refname' directly from <RelPath> as it is always present.
                            If String.IsNullOrEmpty(refName) Then
                                Dim relpatharr() As String = relPath.Split("\"c)
                                refName = relpatharr(relpatharr.Length - 2) '<RelPath> = "\Web References\<name>\"
                            End If

                            'If the url external static url, <UpdateFromURL> element most likely be missing. 
                            'In this case use the "includeUrl"
                            If String.IsNullOrEmpty(webRefUrl) And Not String.IsNullOrEmpty("includeUrl") Then
                                webRefUrl = includeUrl
                            End If

                            'Double check to ensure "includeUrl" and "webRefUrl" are same. If not same then display both
                            If Not String.IsNullOrEmpty(includeUrl) AndAlso String.Compare(webRefUrl, includeUrl, True) <> 0 Then
                                webRefUrl = webRefUrl + "," + includeUrl
                            End If

                            dr = dt.NewRow
                            dr.Item("Reference") = refName
                            dr.Item("Url") = webRefUrl
                            dr.Item("Behavior") = urlBehavior
                            dr.Item("ReferredBy") = assemblyname
                            dr.Item("Project") = lookInProject
                            dt.Rows.Add(dr)

                        End If
                    Next

                End If

                asmnode.WebReferences = dt
                asmnode.RootNameSpace = rootNameSpace

            End If

        End If '// check asmnode

        Return asmnode

    End Function

    Private Sub DetectUnusedReferences(ByVal proj As String)

        Dim objAssmbNode As AssemblyNode
        Dim assemblyname As String
        Dim referencedAssemblieslist As ArrayList = New ArrayList
        Dim unusedreferencelist As ArrayList = New ArrayList
        Dim assemblytype As String = CType(BuildListMapProjToAssmbLoc(proj), String)

        If File.Exists(assemblytype) Then

            Dim assemblyinfo As FileInfo = New FileInfo(assemblytype)
            assemblyname = assemblyinfo.Name

            'Get list of assemblies that are actually referecned and available in the manifest using reflection
            Dim refonlyassmb As System.Reflection.Assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(assemblytype)
            Dim referencedAssemblies As System.Reflection.AssemblyName() = refonlyassmb.GetReferencedAssemblies
            Dim enm As IEnumerator = referencedAssemblies.GetEnumerator
            While enm.MoveNext
                referencedAssemblieslist.Add(CType(enm.Current, System.Reflection.AssemblyName).Name)
            End While

            'Get the list of referecned assemblies avialable from the dependency graph and for eahc of them
            'check if it is avaialble in the 'actual referenced' list or not
            If AssemblyList.Contains(assemblyname) Then
                objAssmbNode = CType(AssemblyList.Item(assemblyname), AssemblyNode)
                Dim en As IDictionaryEnumerator = objAssmbNode.GetChildAssemblies.GetEnumerator
                While en.MoveNext
                    Dim key As String = en.Key.ToString
                    Dim ext As String = key.Substring(key.LastIndexOf("."c), key.Length - key.LastIndexOf("."c))
                    If Not referencedAssemblieslist.Contains(en.Key.ToString.Replace(ext, "")) Then
                        'Found an unused referenced
                        unusedreferencelist.Add(en.Key)
                    End If
                End While
            End If

            'If found atleast one unused reference, make a note of this project
            If unusedreferencelist.Count > 0 Then
                htProjectsWithUnusedReferences.Add(proj, unusedreferencelist)
            End If

        End If
    End Sub

    Private Sub DisplayUnusedReferencesXML()

        Dim _xmldoc As XmlDocument = New XmlDocument

        If htProjectsWithUnusedReferences.Count > 0 Then

            Dim unusedreflogfile As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_PROJECTINFO_LOG_FILENAME_XML

            _xmldoc.Load(unusedreflogfile)

            Dim en As IDictionaryEnumerator = htProjectsWithUnusedReferences.GetEnumerator

            While en.MoveNext
                Dim proj As String = en.Key.ToString
                Dim unusedreflist As ArrayList = TryCast(en.Value, ArrayList)

                Dim projectelement As XmlElement = _xmldoc.SelectSingleNode("//Project[@name='" & proj & "']")

                If projectelement Is Nothing Then
                    projectelement = _xmldoc.CreateElement("Project")
                    projectelement.SetAttribute("name", proj)
                    _xmldoc.DocumentElement.AppendChild(projectelement)
                End If

                Dim _unusedreferenceselement As XmlElement = projectelement.SelectSingleNode("UnusedReferences")

                If _unusedreferenceselement Is Nothing Then
                    _unusedreferenceselement = _xmldoc.CreateElement("UnusedReferences")
                    projectelement.AppendChild(_unusedreferenceselement)
                End If

                If Not unusedreflist Is Nothing Then
                    For i As Integer = 0 To unusedreflist.Count - 1
                        Dim referencenameelement As XmlElement = _xmldoc.CreateElement("ReferenceName")
                        referencenameelement.InnerText = CType(unusedreflist(i), String)
                        _unusedreferenceselement.AppendChild(referencenameelement)
                    Next
                End If
            End While

            _xmldoc.Save(unusedreflogfile)

        End If

    End Sub

    Private Sub DisplayUnusedReferences()
        If htProjectsWithUnusedReferences.Count > 0 Then
            Dim logfile As String = AddBackSlashAtTheEnd(logFileDirError) + UBUILD_UNUSEDREF_LOG_FILENAME
            Dim sbuf As StringBuilder = New StringBuilder
            sbuf.Append("*********************************************************************************************").Append(vbCrLf)
            sbuf.Append("Following is the list of projects with unused references").Append(vbCrLf)
            sbuf.Append("--------------------------------------------------------").Append(vbCrLf)
            sbuf.Append("Definition of 'unused references' - If an assembly A has a reference to another assembly B ").Append(vbCrLf)
            sbuf.Append("but does not have any object created of any of the types available in B,then the assembly B ").Append(vbCrLf)
            sbuf.Append("is said to be'unused' in A and is also not part of the assembly A's manifest.").Append(vbCrLf)
            sbuf.Append("So if A does not access any 'Shared'/'Static' member of B, then B can be removed from A's").Append(vbCrLf)
            sbuf.Append("list of referneces. This will reduce application inter-dependency ").Append(vbCrLf)
            sbuf.Append("*********************************************************************************************").Append(vbCrLf)
            WriteLog(logfile, sbuf.ToString)
            Dim en As IDictionaryEnumerator = htProjectsWithUnusedReferences.GetEnumerator
            While en.MoveNext
                Dim proj As String = en.Key.ToString
                Dim unusedreflist As ArrayList = TryCast(en.Value, ArrayList)
                If Not unusedreflist Is Nothing Then
                    WriteLog(logfile, proj)
                    For i As Integer = 0 To unusedreflist.Count - 1
                        WriteLog(logfile, vbTab + CType(unusedreflist(i), String))
                    Next
                End If
            End While
        End If
    End Sub

    Private Sub UpdateProjectProperties()

        'All the properties,  lists and hashtable mapping, first gets set in the GenerateBuildList() function
        'Since we re-sync after the ordered build list has been generated we have to update the necessary project properties and re-create the lists and mappings
        htOutputType.Clear()
        htOutputPath.Clear()
        BuildListMapProjToAssmbLoc.Clear()
        BuildListMapProjToAssmbName.Clear()

        'For all the projects in the generated ordered build list, update the project properties
        For i As Integer = 0 To SortedBuildList.Count - 1
            Dim proj As String = CType(SortedBuildList(i), String)
            UpdateProjectOutputPath(proj)
            UpdateHintPath(proj)
        Next

    End Sub

    Private Sub SetupTargetFrameworkVersion(ByVal proj As String)

        If GetDotNetVersion(proj) = DOTNETVERSION.TWO Then

            Dim targetfraemworkversionelement As XmlElement

            Dim xmldoc As XmlDocument = New XmlDocument
            File.SetAttributes(proj, FileAttributes.Normal)
            xmldoc.Load(proj)

            'We need the NamespaceManager when using SelectNodes becuase the project file contians a default namespace
            'So without creating a namespace prefix, SelectNodes will return nothing
            Dim projectNameSpaceURI As String = CType(xmldoc.FirstChild, System.Xml.XmlNode).NamespaceURI
            Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xmldoc.NameTable)
            nsmgr.AddNamespace("proj", projectNameSpaceURI)

            Dim xpathquery As String = "//proj:PropertyGroup"

            Dim nl As XmlNodeList = xmldoc.DocumentElement.SelectNodes(xpathquery, nsmgr)

            Dim firstpropertygroupelement As XmlElement = nl.Item(0)

            'Check if the '<TargetFrameworkVersion> element is present
            Dim _nlTargetFrameworkVersion As XmlNodeList = xmldoc.GetElementsByTagName("TargetFrameworkVersion")

            If Not _nlTargetFrameworkVersion Is Nothing Then

                If _nlTargetFrameworkVersion.Count = 0 Then

                    'Create the element
                    targetfraemworkversionelement = xmldoc.CreateElement("TargetFrameworkVersion", projectNameSpaceURI)
                    targetfraemworkversionelement.InnerText = targetFrameworkVersion

                    'Add it to the project
                    If Not firstpropertygroupelement Is Nothing Then
                        firstpropertygroupelement.AppendChild(targetfraemworkversionelement)
                    End If

                Else
                    'Update the target version
                    targetfraemworkversionelement = xmldoc.GetElementsByTagName("TargetFrameworkVersion").Item(0)
                    targetfraemworkversionelement.InnerText = targetFrameworkVersion
                End If

                'Save
                xmldoc.Save(proj)
            End If








        End If

    End Sub

    Private Sub SetupGenerateSerializationAssemblies(ByVal proj As String)

        If GetDotNetVersion(proj) = DOTNETVERSION.TWO Then

            Dim xmldoc As XmlDocument = New XmlDocument
            File.SetAttributes(proj, FileAttributes.Normal)
            xmldoc.Load(proj)

            'We need the NamespaceManager when using SelectNodes becuase the project file contians a default namespace
            'So without creating a namespace prefix, SelectNodes will return nothing
            Dim projectNameSpaceURI As String = CType(xmldoc.FirstChild, System.Xml.XmlNode).NamespaceURI
            Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xmldoc.NameTable)
            nsmgr.AddNamespace("proj", projectNameSpaceURI)

            Dim xpathquery As String = "//proj:PropertyGroup/@Condition"

            Dim sgenassembly As XmlElement = Nothing
            Dim propgroup As XmlElement = Nothing
            Dim nl As XmlNodeList = xmldoc.DocumentElement.SelectNodes(xpathquery, nsmgr)
            For Each attr As XmlAttribute In nl
                Dim config As String = attr.Value
                If config.IndexOf("Release") > -1 Then
                    If attr.OwnerElement.GetElementsByTagName("GenerateSerializationAssemblies").Count = 0 Then
                        propgroup = attr.OwnerElement
                        sgenassembly = xmldoc.CreateElement("GenerateSerializationAssemblies", projectNameSpaceURI)
                        sgenassembly.InnerText = genSerializeAssembly
                    Else
                        attr.OwnerElement.GetElementsByTagName("GenerateSerializationAssemblies").Item(0).InnerText = genSerializeAssembly
                    End If
                End If
            Next

            If Not propgroup Is Nothing Then
                propgroup.AppendChild(sgenassembly)
            End If

            xmldoc.Save(proj)

        End If

    End Sub

    Private Sub UpdateProjectOutputPath(ByVal proj As String)

        Dim assmbly As String = ""
        Dim outputType As String = ""
        Dim outputPath As String = "bin\"
        Dim projconfig As String = ""
        Dim FileExtension As String = String.Empty

        'Make the project name all lower case
        proj = proj.ToLower

        If GetDotNetVersion(proj) = DOTNETVERSION.TWO Then

            Dim xmldoc As XmlDocument = New XmlDocument
            File.SetAttributes(proj, FileAttributes.Normal)
            xmldoc.Load(proj)

            projconfig = xmldoc.GetElementsByTagName("Configuration").Item(0).InnerText
            assmbly = xmldoc.GetElementsByTagName("AssemblyName").Item(0).InnerText
            outputType = xmldoc.GetElementsByTagName("OutputType").Item(0).InnerText

            'Update the output path of the project's assembly to \bin folder
            Dim oplist As XmlNodeList = xmldoc.GetElementsByTagName("OutputPath")
            For Each xelement As XmlElement In oplist
                xelement.InnerText = "bin\"
            Next
            xmldoc.Save(proj)
            xmldoc = Nothing

            File.SetAttributes(proj, FileAttributes.ReadOnly)

            'Check for the assembly output type and save it
            If Not outputType Is Nothing Then
                Select Case outputType.ToLower
                    Case "winexe", "exe"
                        FileExtension = "exe"
                    Case "library"
                        FileExtension = "dll"
                End Select

                If Not htOutputType.Contains(proj) Then
                    htOutputType.Add(proj, FileExtension)
                End If

            End If

            'Save the output path of the project
            If Not assmbly Is Nothing And Not outputPath Is Nothing Then
                If Not htOutputPath.Contains(assmbly + "." + FileExtension) Then
                    htOutputPath.Add(assmbly + "." + FileExtension, outputPath)
                End If
            End If

            'Get the compiled assembly location of the project 
            SetupAssemblyLocation(proj, assmbly + "." + FileExtension)

        Else
            'DOTNET_VER 1.1

            Dim xmldoc As XmlDocument = New XmlDocument
            File.SetAttributes(proj, FileAttributes.Normal)
            xmldoc.Load(proj)

            Dim configList As XmlNodeList = xmldoc.SelectNodes("//Build/Settings/Config")
            Dim settingsList As XmlNodeList = xmldoc.SelectNodes("//Build/Settings")

            For Each settingelement As XmlElement In settingsList
                If settingelement.HasAttribute("AssemblyName") Then
                    assmbly = settingelement.GetAttribute("AssemblyName")
                End If
                If settingelement.HasAttribute("OutputType") Then
                    outputType = settingelement.GetAttribute("OutputType")
                End If
            Next

            For Each configelment As XmlElement In configList
                If configelment.HasAttribute("OutputPath") Then
                    configelment.SetAttribute("OutputPath", "bin\")
                End If
            Next

            xmldoc.Save(proj)
            xmldoc = Nothing

            File.SetAttributes(proj, FileAttributes.ReadOnly)

            'Check for the assembly output type and save it
            If Not outputType Is Nothing Then
                Select Case outputType.ToLower
                    Case "winexe", "exe"
                        FileExtension = "exe"
                    Case "library"
                        FileExtension = "dll"
                End Select

                If Not htOutputType.Contains(proj) Then
                    htOutputType.Add(proj, FileExtension)
                End If

            End If

            'Save the output path of the project
            If Not assmbly Is Nothing And Not outputPath Is Nothing Then
                If Not htOutputPath.Contains(assmbly + "." + FileExtension) Then
                    htOutputPath.Add(assmbly + "." + FileExtension, outputPath)
                End If
            End If

            'Get the compiled assembly location of the project 
            SetupAssemblyLocation(proj, assmbly + "." + FileExtension)

        End If '//end check DOTNET_VER
    End Sub

    Private Sub SetupAssemblyLocation(ByVal proj As String, ByVal assmbNameWithExt As String)

        'Setup the compiled assembly name and location of the project  and also cleans the output directory if performing a major build

        Dim sbuf As New StringBuilder
        Dim sbufdir As New StringBuilder
        Dim outputDir As String

        Dim tmparr As String() = proj.Split("\"c)
        Dim tmpOutput As String() = tmparr.Clone
        Dim arrlength As Integer = tmparr.Length

        tmpOutput(arrlength - 1) = CType(htOutputPath(assmbNameWithExt), String)
        tmparr(arrlength - 1) = CType(htOutputPath(assmbNameWithExt), String) + assmbNameWithExt

        Dim builtAssmbLocation As String
        For indx As Integer = 0 To arrlength - 1
            sbuf.Append(tmparr(indx)).Append("\")
            sbufdir.Append(tmpOutput(indx)).Append("\")
        Next

        outputDir = sbufdir.ToString.Substring(0, sbufdir.ToString.Length - 1)
        builtAssmbLocation = sbuf.ToString.Substring(0, sbuf.ToString.Length - 1)

        If String.Compare(buildType, "rebuild", True) = 0 Then
            CleanOutputDir(outputDir)
        End If

        If Not BuildListMapProjToAssmbLoc.Contains(proj) Then
            BuildListMapProjToAssmbLoc.Add(proj, builtAssmbLocation)
        End If
        If Not BuildListMapProjToAssmbName.Contains(proj) Then
            BuildListMapProjToAssmbName.Add(proj, (CType(ProjectsToAssmb(proj), String)))
        End If
    End Sub

    Private Sub ReSynchronizeProjectsToBuild()

        If Not blReSyncInParallel Then

            WriteLog("ReSynchronizing Projects To Build ...")
            For i As Integer = 0 To SortedBuildList.Count - 1
                ReSyncSource(CType(SortedBuildList(i), String))
            Next

        Else

            WriteLog("ReSynchronizing Projects To Build ... In Parallel")

            NosOfProjectsToReSync = SortedBuildList.Count - 1

            For i As Integer = 0 To SortedBuildList.Count - 1

                Dim parallelresyncprojarg As ParallelReSyncSourceArgs = New ParallelReSyncSourceArgs
                parallelresyncprojarg.mProjName = CType(SortedBuildList(i), String)
                parallelresyncprojarg.ReSyncSourceDelegate = AddressOf ReSyncSource

                Dim t As New Thread(AddressOf parallelresyncprojarg.ReSynSource)
                t.IsBackground = True
                t.Priority = ThreadPriority.Lowest
                t.Start()

            Next

            While NosOfProjectsToReSync <> 0
                ' Spinlock wait - can use Thread.Sleep(5000) for little better performance
            End While

            'Display the log
            For j As Integer = 0 To ParallelReSyncSourceLog.Count - 1
                WriteLog(DirectCast(ParallelReSyncSourceLog(j), String))
            Next

        End If


    End Sub

    Private Sub ReSyncSource(ByVal proj As String)

        Dim p As Process
        Dim psi As ProcessStartInfo = New ProcessStartInfo
        Dim exitcode As Integer
        Dim buildArg As String = String.Empty
        Dim mksproj As String = String.Empty
        Dim logstmt As String = String.Empty

        Dim tmparr() As String = proj.Split("\"c)
        Dim projname As String = tmparr(tmparr.Length - 1)

        mksproj = proj.Replace(projname, "project.pj")

        'buildArg = "resync -f -R -S " + """" + mksproj + """" + " -Y"
        buildArg = "resync " + resyncOptions.Trim + " " + """" + mksproj + """" + " -Y"

        psi.FileName = """" + MKS_SI + """"
        psi.WindowStyle = ProcessWindowStyle.Hidden
        'psi.ErrorDialog = True
        psi.UseShellExecute = False
        psi.Arguments = buildArg

        p = Process.Start(psi)
        p.WaitForExit()
        exitcode = p.ExitCode
        p.Close()

        If exitcode <> 0 Then
            logstmt = "ReSynchornizing files  :  " + proj + " [FAILURE] "
        Else
            logstmt = "ReSynchornizing files  :  " + proj + " [SUCCESS] "
        End If

        If blReSyncInParallel Then
            ParallelReSyncSourceLog.Add(logstmt)
        Else
            WriteLog(logstmt)
        End If

        If blReSyncInParallel Then
            Dim objLock As Object = New Object
            SyncLock objLock
                NosOfProjectsToReSync = NosOfProjectsToReSync - 1
            End SyncLock
        End If

    End Sub

    Private Sub ParseUBuildErrorLog(ByVal errlogfile As String)
        Dim dirname As String = String.Empty
        Dim projname As String = String.Empty
        Dim errfilelist As New ArrayList

        failedprojectname = String.Empty
        errfilename = String.Empty
        errordesc = String.Empty
        errorlinenumber = String.Empty
        errorcode = String.Empty
        revnumber = String.Empty
        lockedin = String.Empty
        createdauthorname = String.Empty
        lockedbyauthorname = String.Empty
        createddatetime = String.Empty
        lockeddatetime = String.Empty

        Dim xmldoc As XmlDocument = New XmlDocument
        xmldoc.Load(errlogfile)

        If xmldoc.GetElementsByTagName("project").Count > 0 Then
            Dim projelementlist As XmlNodeList = xmldoc.GetElementsByTagName("project")
            For Each projelement As XmlElement In projelementlist
                Dim attribcol As XmlAttributeCollection = projelement.Attributes
                For Each attrib As XmlAttribute In attribcol
                    Dim attribname As String = attrib.Name.ToLower()
                    Select Case attribname
                        Case "file"
                            failedprojectname = projelement.Attributes("file").Value
                        Case "dir"
                            dirname = projelement.Attributes("dir").Value
                            If projelement.HasAttribute("name") AndAlso String.Compare(dirname, String.Empty) <> 0 Then
                                projname = projelement.Attributes("name").Value
                                failedprojectname = AddBackSlashAtTheEnd(dirname) + projname
                            End If
                    End Select
                Next
            Next
        End If

        If xmldoc.GetElementsByTagName("error").Count > 0 Then
            Dim errlist As XmlNodeList = xmldoc.GetElementsByTagName("error")
            For Each errelement As XmlElement In errlist
                errfilename = String.Empty
                errorcode = String.Empty
                Dim attribcol As XmlAttributeCollection = errelement.Attributes
                For Each attrib As XmlAttribute In attribcol
                    Dim attribname As String = attrib.Name.ToLower()
                    Select Case attribname
                        Case "code"
                            errorcode = errelement.Attributes("code").Value
                        Case "file"
                            errfilename = errelement.Attributes("file").Value
                            errordesc = errelement.InnerXml.Trim
                            If errelement.HasAttribute("line") Then
                                errorlinenumber = errelement.Attributes("line").Value
                            End If
                        Case "dir"
                            If errelement.HasAttribute("name") AndAlso String.Compare(errelement.Attributes("dir").Value, String.Empty) <> 0 Then
                                errfilename = AddBackSlashAtTheEnd(errelement.Attributes("dir").Value) + errelement.Attributes("name").Value
                            End If
                        Case "message"
                            errordesc = errelement.Attributes("message").Value
                        Case "pos"
                            errorlinenumber = errelement.Attributes("pos").Value
                    End Select
                Next
                If String.Compare(errfilename, String.Empty) <> 0 AndAlso File.Exists(errfilename) Then
                    If Not errorcode.StartsWith("MS") Then
                        If Not errfilelist.Contains(errfilename) Then
                            errfilelist.Add(errfilename)
                        End If
                        ExtractMKSMemberRevisionInfo(GetMKSMemberRevisionInfo(errfilename))
                    End If
                Else
                    errfilename = String.Empty
                End If
                WriteLogUBuildErrorDetail()
            Next
        End If

        xmldoc = Nothing

    End Sub

    'Private Sub ParseUBuildErrorLog(ByVal errlogfile As String)
    '    Dim errfilelist As New ArrayList
    '    Dim xmldoc As XmlDocument = New XmlDocument
    '    xmldoc.Load(errlogfile)
    '    If xmldoc.GetElementsByTagName("project").Count = 1 Then
    '        Dim projelement As XmlElement = xmldoc.GetElementsByTagName("project").Item(0)
    '        If projelement.HasAttribute("file") Then
    '            failedprojectname = projelement.Attributes("file").Value
    '        End If
    '    End If
    '    If xmldoc.GetElementsByTagName("error").Count > 0 Then
    '        Dim errlist As XmlNodeList = xmldoc.GetElementsByTagName("error")
    '        For Each errelement As XmlElement In errlist
    '            errordesc = errelement.InnerXml.Trim
    '            If errelement.HasAttribute("line") Then
    '                errorlinenumber = errelement.Attributes("line").Value
    '            End If
    '            If errelement.HasAttribute("file") Then
    '                errfilename = errelement.Attributes("file").Value
    '                If Not errfilelist.Contains(errfilename) Then
    '                    errfilelist.Add(errfilename)
    '                    ExtractMKSMemberRevisionInfo(GetMKSMemberRevisionInfo(errfilename))
    '                End If
    '                WriteLogUBuildErrorDetail()
    '            End If

    '        Next
    '    End If
    '    xmldoc = Nothing
    'End Sub

    Private Function GetMKSMemberRevisionInfo(ByVal membername As String) As String
        Dim p As Process
        Dim psi As ProcessStartInfo = New ProcessStartInfo
        Dim exitcode As Integer
        Dim buildArg As String = ""
        Dim out As String = ""

        If File.Exists(membername) Then
            buildArg = " revisioninfo " + """" + membername + """"
            psi.FileName = """" + MKS_SI + """"
            psi.WindowStyle = ProcessWindowStyle.Hidden
            psi.RedirectStandardOutput = True
            psi.UseShellExecute = False
            psi.Arguments = buildArg

            p = Process.Start(psi)
            p.WaitForExit()
            exitcode = p.ExitCode
            out = p.StandardOutput.ReadToEnd
            p.Close()
        End If


        Return out


    End Function

    Private Sub ExtractMKSMemberRevisionInfo(ByVal content As String)

        Dim revfilecontent As String = content
        Dim revpattren As String = "Revision:\s*(?<revision>[\d\.]+)"
        Dim createdbydatetimepattern As String = "Created By:\s*(?<createdby>.*)\s+on\s+(?<datetime>.*)"
        Dim lockedbydatetimepattern As String = "Locked By:\s*(?<lockedby>.*)\s+on\s+(?<datetime>.*)"
        Dim lockedinpattern As String = "Locked In:\s*(?<lockedin>.*)"

        Dim regexobj As Regex
        Dim matches As MatchCollection

        regexobj = New Regex(revpattren)
        matches = regexobj.Matches(revfilecontent)
        If matches.Count > 0 Then
            revnumber = matches(0).Groups("revision").Value()
        End If

        regexobj = New Regex(createdbydatetimepattern)
        matches = regexobj.Matches(revfilecontent)
        If matches.Count > 0 Then
            createdauthorname = matches(0).Groups("createdby").Value()
            createddatetime = matches(0).Groups("datetime").Value()
        End If

        regexobj = New Regex(lockedbydatetimepattern)
        matches = regexobj.Matches(revfilecontent)
        If matches.Count > 0 Then
            lockedbyauthorname = matches(0).Groups("lockedby").Value()
            lockeddatetime = matches(0).Groups("datetime").Value()
        End If

        regexobj = New Regex(lockedinpattern)
        matches = regexobj.Matches(revfilecontent)
        If matches.Count > 0 Then
            lockedin = matches(0).Groups("lockedin").Value()
        End If

        Output("FileName : " + errfilename, ConsoleTools.ConsoleColor.red)
        Output("Revision# : " + revnumber, ConsoleTools.ConsoleColor.red)
        Output("Last Modified By : " + createdauthorname, ConsoleTools.ConsoleColor.red)
        Output("Last Modified On : " + createddatetime, ConsoleTools.ConsoleColor.red)
        'Output("Locked By : " + lockedbyauthorname, ConsoleTools.ConsoleColor.red)
        'Output("Locked On : " + lockeddatetime, ConsoleTools.ConsoleColor.red)
        'Output("Locked In : " + lockedin, ConsoleTools.ConsoleColor.red)


    End Sub

    Private Sub WriteLogUBuildErrorDetail()

        'Write the error details into a log file

        Dim xmldoc As XmlDocument = New XmlDocument
        xmldoc.Load(UBuildErrorDetailFile)

        Dim root As XmlElement
        Dim failedprojectelement As XmlElement
        Dim errdetail As XmlElement
        Dim failedfileelement As XmlElement
        Dim errordescelement As XmlElement
        Dim errlinenumberelement As XmlElement
        Dim revelement As XmlElement
        Dim lastmodifiedbyelement As XmlElement
        Dim lastmodifiedonelement As XmlElement
        Dim lockedbyelement As XmlElement
        Dim lockedonelement As XmlElement
        Dim lockedinelement As XmlElement


        If xmldoc.GetElementsByTagName("BuildErrors").Count = 1 Then
            root = xmldoc.GetElementsByTagName("BuildErrors").Item(0)
        Else
            root = xmldoc.CreateElement("BuildErrors")
            xmldoc.AppendChild(root)
        End If

        root.SetAttribute("buildname", buildname)
        'root.SetAttribute("project", failedprojectname)

        failedprojectelement = xmldoc.SelectSingleNode("//FailedProject[@name='" + failedprojectname + "']")

        If failedprojectelement Is Nothing Then
            failedprojectelement = xmldoc.CreateElement("FailedProject")
            failedprojectelement.SetAttribute("name", failedprojectname)
        End If

        errdetail = xmldoc.CreateElement("ErrorDetail")

        failedfileelement = xmldoc.CreateElement("Filename")
        errordescelement = xmldoc.CreateElement("Error")
        errlinenumberelement = xmldoc.CreateElement("LineNumber")
        revelement = xmldoc.CreateElement("Revision")
        lastmodifiedbyelement = xmldoc.CreateElement("LastModifiedBy")
        lastmodifiedonelement = xmldoc.CreateElement("LastModifiedOn")
        lockedbyelement = xmldoc.CreateElement("LockedBy")
        lockedonelement = xmldoc.CreateElement("LockedOn")
        lockedinelement = xmldoc.CreateElement("LockedIn")

        failedfileelement.InnerText = errfilename
        errordescelement.InnerText = errordesc
        errlinenumberelement.InnerText = errorlinenumber
        revelement.InnerText = revnumber
        lastmodifiedbyelement.InnerText = GetUserName(createdauthorname)
        lastmodifiedonelement.InnerText = createddatetime
        lockedbyelement.InnerText = lockedbyauthorname
        lockedonelement.InnerText = lockeddatetime
        lockedinelement.InnerText = lockedin

        errdetail.AppendChild(failedfileelement)
        errdetail.AppendChild(errlinenumberelement)
        errdetail.AppendChild(errordescelement)
        errdetail.AppendChild(revelement)
        errdetail.AppendChild(lastmodifiedbyelement)
        errdetail.AppendChild(lastmodifiedonelement)
        errdetail.AppendChild(lockedbyelement)
        errdetail.AppendChild(lockedonelement)
        errdetail.AppendChild(lockedinelement)

        failedprojectelement.AppendChild(errdetail)

        root.AppendChild(failedprojectelement)

        xmldoc.Save(UBuildErrorDetailFile)

        xmldoc = Nothing

    End Sub

#End Region

#Region "Logs"

    Private Sub WriteLog(ByVal logfilename As String, ByVal logtxt As String, Optional ByVal newline As Boolean = True)
        If File.Exists(logfilename) Then
            Dim sw As StreamWriter
            sw = File.AppendText(logfilename)
            If newline Then
                sw.WriteLine(logtxt)
            Else
                sw.Write(logtxt)
            End If
            sw.Close()
            sw = Nothing
        End If
    End Sub

    Private Sub WriteLog(ByVal logtxt As String, Optional ByVal newline As Boolean = True)
        WriteLog(txtLogFile, logtxt, newline)
        'If File.Exists(txtLogFile) Then
        '    Dim sw As StreamWriter
        '    sw = File.AppendText(txtLogFile)
        '    If newline Then
        '        sw.WriteLine(logtxt)
        '    Else
        '        sw.Write(logtxt)
        '    End If
        '    sw.Close()
        '    sw = Nothing
        'End If
    End Sub

#End Region

#Region "Notification"

    Private Sub SendBuildStatusToNotificationServer(ByVal errdetailfile As String)

        Dim ipHostInfo As IPHostEntry = Dns.GetHostEntry(NOTIFICATION_SERVER)
        Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
        Dim remoteEP As New IPEndPoint(ipAddress, NOTIFICATION_SERVER_PORT)
        Dim bs As Byte()
        Dim msg As MessageClass = Util.CreateDefaultMessage

        'Set the message text
        msg.MessageText = "Build Notification Status"

        'Create the payload
        If String.Compare(errdetailfile, String.Empty) <> 0 And File.Exists(errdetailfile) Then
            msg.Payload = GetBuildResultDetail(errdetailfile)
        End If

        ' Create a TCP/IP socket.
        Dim sender As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        ' Connect the socket to the remote endpoint.
        Try
            sender.Connect(remoteEP)
            Console.WriteLine(Dns.GetHostName + " connected to {0}", sender.RemoteEndPoint.ToString())

            bs = Util.CreateMessage(msg.MessageType, msg.MessageText, msg.MessageSender, msg.Payload)

            ' Send the data through the socket.
            Dim bytesSent As Integer = sender.Send(bs)

            ' Release the socket.
            sender.Shutdown(SocketShutdown.Send)
            sender.Close()

        Catch ex As SocketException
            Console.WriteLine(ex.Message.ToString)
        End Try

    End Sub

    Private Function GetBuildResultDetail(ByVal errfile As String) As String
        Dim result As String = ""
        Dim xmldoc As Xml.XmlDocument = New Xml.XmlDocument
        xmldoc.Load(errfile)
        If xmldoc.HasChildNodes Then
            result = xmldoc.InnerXml.Trim
        Else
            result = "SUCCESS"
        End If
        xmldoc = Nothing
        Return result
    End Function

#End Region

#Region " Private Classes"

    Private Class ParallelBuildArgs

        Public mProjName As String
        Public mProjectCount As Integer
        Public StartParallelBuildDelegate As ParallelBuildDelegate

        Public Sub DoBuild()
            StartParallelBuildDelegate(mProjName, mProjectCount)
        End Sub

    End Class

    Private Class ParallelReSyncSourceArgs

        Public mProjName As String
        Public ReSyncSourceDelegate As ParallelReSyncSourceDelegate

        Public Sub ReSynSource()
            ReSyncSourceDelegate(mProjName)
        End Sub

    End Class

#End Region

End Module
